Field3D
DenseField.h
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
42 //----------------------------------------------------------------------------//
43 
44 #ifndef _INCLUDED_Field3D_DenseField_H_
45 #define _INCLUDED_Field3D_DenseField_H_
46 
47 #include <vector>
48 
49 #include <boost/lexical_cast.hpp>
50 
51 #include "Field.h"
52 
53 //----------------------------------------------------------------------------//
54 
55 #include "ns.h"
56 
58 
59 //----------------------------------------------------------------------------//
60 // Forward declarations
61 //----------------------------------------------------------------------------//
62 
63 template <class Field_T>
65 template <class Field_T>
67 
68 //----------------------------------------------------------------------------//
69 // DenseField
70 //----------------------------------------------------------------------------//
71 
79 //----------------------------------------------------------------------------//
80 
81 template <class Data_T>
83  : public ResizableField<Data_T>
84 {
85 public:
86 
87  // Typedefs ------------------------------------------------------------------
88 
89  typedef boost::intrusive_ptr<DenseField> Ptr;
90  typedef std::vector<Ptr> Vec;
91 
94 
96 
97  // Constructors --------------------------------------------------------------
98 
101 
103  DenseField();
104 
105  // \}
106 
107  // Main methods --------------------------------------------------------------
108 
110  virtual void clear(const Data_T &value);
111 
112  // From Field base class -----------------------------------------------------
113 
116  virtual Data_T value(int i, int j, int k) const;
117  virtual long long int memSize() const;
119 
120  // RTTI replacement ----------------------------------------------------------
121 
124 
125  static const char *staticClassName()
126  {
127  return "DenseField";
128  }
129 
130  static const char *classType()
131  {
133  }
134 
135  // From WritableField base class ---------------------------------------------
136 
139  virtual Data_T& lvalue(int i, int j, int k);
141 
142  // Concrete voxel access -----------------------------------------------------
143 
145  const Data_T& fastValue(int i, int j, int k) const;
147  Data_T& fastLValue(int i, int j, int k);
148 
149  // Iterators -----------------------------------------------------------------
150 
153 
155  class const_iterator;
156 
158  class iterator;
159 
161  const_iterator cbegin() const;
163  const_iterator cbegin(const Box3i &subset) const;
165  const_iterator cend() const;
168  const_iterator cend(const Box3i &subset) const;
170  iterator begin();
172  iterator begin(const Box3i &subset);
174  iterator end();
177  iterator end(const Box3i &subset);
178 
180 
181  // Utility methods -----------------------------------------------------------
182 
186  const FIELD3D_VEC3_T<size_t> &internalMemSize() const
187  { return m_memSize; }
188 
189  // From FieldBase ------------------------------------------------------------
190 
193 
194  virtual std::string className() const
195  { return staticClassName(); }
196 
197  virtual FieldBase::Ptr clone() const
198  { return Ptr(new DenseField(*this)); }
199 
201 
202 protected:
203 
204  // From ResizableField class -------------------------------------------------
205 
206  virtual void sizeChanged();
207 
208  // Data members --------------------------------------------------------------
209 
211  FIELD3D_VEC3_T<size_t> m_memSize;
213  size_t m_memSizeXY;
215  std::vector<Data_T> m_data;
216 
217 private:
218 
219  // Static data members -------------------------------------------------------
220 
222 
223  // Direct access to memory for iterators -------------------------------------
224 
226  inline Data_T* ptr(int i, int j, int k);
228  inline const Data_T* ptr(int i, int j, int k) const;
229 
230 };
231 
232 //----------------------------------------------------------------------------//
233 // Typedefs
234 //----------------------------------------------------------------------------//
235 
242 
243 //----------------------------------------------------------------------------//
244 // DenseField::const_iterator
245 //----------------------------------------------------------------------------//
246 
247 template <class Data_T>
249 {
250 public:
251 
252  // Typedefs ------------------------------------------------------------------
253 
255 
256  // Constructors --------------------------------------------------------------
257 
258  const_iterator(const class_type &field, const Box3i &window,
259  const V3i &currentPos)
260  : x(currentPos.x), y(currentPos.y), z(currentPos.z),
261  m_window(window), m_field(field)
262  { m_p = m_field.ptr(x, y, z); }
263 
264  // Operators -----------------------------------------------------------------
265 
266  const const_iterator& operator ++ ()
267  {
268  if (x == m_window.max.x) {
269  if (y == m_window.max.y) {
270  m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
271  } else {
272  m_p = m_field.ptr(x = m_window.min.x, ++y, z);
273  }
274  } else {
275  ++x;
276  ++m_p;
277  }
278  return *this;
279  }
280 
281  template <class Iter_T>
282  inline bool operator == (const Iter_T &rhs) const
283  {
284  return m_p == &(*rhs);
285  }
286 
287  template <class Iter_T>
288  inline bool operator != (const Iter_T &rhs) const
289  {
290  return m_p != &(*rhs);
291  }
292 
293  inline const Data_T& operator * () const
294  {
295  return *m_p;
296  }
297 
298  inline const Data_T* operator -> () const
299  {
300  return m_p;
301  }
302 
303  // Public data members -------------------------------------------------------
304 
306  int x, y, z;
307 
308 private:
309 
310  // Private data members ------------------------------------------------------
311 
313  const Data_T *m_p;
317  const class_type &m_field;
318 
319 };
320 
321 //----------------------------------------------------------------------------//
322 // DenseField::iterator
323 //----------------------------------------------------------------------------//
324 
325 template <class Data_T>
326 class DenseField<Data_T>::iterator
327 {
328 public:
329 
330  // Typedefs ------------------------------------------------------------------
331 
333 
334  // Constructors --------------------------------------------------------------
335 
336  iterator(class_type &field, const Box3i &window,
337  const V3i &currentPos)
338  : x(currentPos.x), y(currentPos.y), z(currentPos.z),
339  m_window(window), m_field(field)
340  { m_p = m_field.ptr(x, y, z); }
341 
342  // Operators -----------------------------------------------------------------
343 
344  const iterator& operator ++ ()
345  {
346  if (x == m_window.max.x) {
347  if (y == m_window.max.y) {
348  m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
349  } else {
350  m_p = m_field.ptr(x = m_window.min.x, ++y, z);
351  }
352  } else {
353  ++x;
354  ++m_p;
355  }
356  return *this;
357  }
358 
359  template <class Iter_T>
360  inline bool operator == (const Iter_T &rhs) const
361  {
362  return m_p == &(*rhs);
363  }
364 
365  template <class Iter_T>
366  inline bool operator != (const Iter_T &rhs) const
367  {
368  return m_p != &(*rhs);
369  }
370 
371  inline Data_T& operator * () const
372  {
373  return *m_p;
374  }
375 
376  inline Data_T* operator -> () const
377  {
378  return m_p;
379  }
380 
381  // Public data members -------------------------------------------------------
382 
384  int x, y, z;
385 
386 private:
387 
388  // Private data members ------------------------------------------------------
389 
391  Data_T *m_p;
395  class_type &m_field;
396 };
397 
398 //----------------------------------------------------------------------------//
399 // DenseField implementations
400 //----------------------------------------------------------------------------//
401 
402 template <class Data_T>
404  : base(),
405  m_memSize(0), m_memSizeXY(0)
406 {
407  // Empty
408 }
409 
410 //----------------------------------------------------------------------------//
411 
412 template <class Data_T>
413 void DenseField<Data_T>::clear(const Data_T &value)
414 {
415  std::fill(m_data.begin(), m_data.end(), value);
416 }
417 
418 //----------------------------------------------------------------------------//
419 
420 template <class Data_T>
421 Data_T DenseField<Data_T>::value(int i, int j, int k) const
422 {
423  return fastValue(i, j, k);
424 }
425 
426 //----------------------------------------------------------------------------//
427 
428 template <class Data_T>
429 long long int DenseField<Data_T>::memSize() const
430 {
431  long long int superClassMemSize = base::memSize();
432  long long int vectorMemSize = m_data.capacity() * sizeof(Data_T);
433  return sizeof(*this) + vectorMemSize + superClassMemSize;
434 }
435 
436 //----------------------------------------------------------------------------//
437 
438 template <class Data_T>
439 Data_T& DenseField<Data_T>::lvalue(int i, int j, int k)
440 {
441  return fastLValue(i, j, k);
442 }
443 
444 //----------------------------------------------------------------------------//
445 
446 template <class Data_T>
447 const Data_T& DenseField<Data_T>::fastValue(int i, int j, int k) const
448 {
449  assert (i >= base::m_dataWindow.min.x);
450  assert (i <= base::m_dataWindow.max.x);
451  assert (j >= base::m_dataWindow.min.y);
452  assert (j <= base::m_dataWindow.max.y);
453  assert (k >= base::m_dataWindow.min.z);
454  assert (k <= base::m_dataWindow.max.z);
455  // Add crop window offset
456  i -= base::m_dataWindow.min.x;
457  j -= base::m_dataWindow.min.y;
458  k -= base::m_dataWindow.min.z;
459  // Access data
460  return m_data[i + j * m_memSize.x + k * m_memSizeXY];
461 }
462 
463 //----------------------------------------------------------------------------//
464 
465 template <class Data_T>
466 Data_T& DenseField<Data_T>::fastLValue(int i, int j, int k)
467 {
468  assert (i >= base::m_dataWindow.min.x);
469  assert (i <= base::m_dataWindow.max.x);
470  assert (j >= base::m_dataWindow.min.y);
471  assert (j <= base::m_dataWindow.max.y);
472  assert (k >= base::m_dataWindow.min.z);
473  assert (k <= base::m_dataWindow.max.z);
474  // Add crop window offset
475  i -= base::m_dataWindow.min.x;
476  j -= base::m_dataWindow.min.y;
477  k -= base::m_dataWindow.min.z;
478  // Access data
479  return m_data[i + j * m_memSize.x + k * m_memSizeXY];
480 }
481 
482 //----------------------------------------------------------------------------//
483 
484 template <class Data_T>
487 {
488  if (FieldRes::dataResolution() == V3i(0))
489  return cend();
490  return const_iterator(*this, base::m_dataWindow, base::m_dataWindow.min);
491 }
492 
493 //----------------------------------------------------------------------------//
494 
495 template <class Data_T>
497 DenseField<Data_T>::cbegin(const Box3i &subset) const
498 {
499  if (subset.isEmpty())
500  return cend(subset);
501  return const_iterator(*this, subset, subset.min);
502 }
503 
504 //----------------------------------------------------------------------------//
505 
506 template <class Data_T>
509 {
510  return const_iterator(*this, base::m_dataWindow,
511  V3i(base::m_dataWindow.min.x,
512  base::m_dataWindow.min.y,
513  base::m_dataWindow.max.z + 1));
514 }
515 
516 //----------------------------------------------------------------------------//
517 
518 template <class Data_T>
520 DenseField<Data_T>::cend(const Box3i &subset) const
521 {
522  return const_iterator(*this, subset,
523  V3i(subset.min.x, subset.min.y, subset.max.z + 1));
524 }
525 
526 //----------------------------------------------------------------------------//
527 
528 template <class Data_T>
531 {
532  if (FieldRes::dataResolution() == V3i(0))
533  return end();
534  return iterator(*this, base::m_dataWindow, base::m_dataWindow.min); }
535 
536 //----------------------------------------------------------------------------//
537 
538 template <class Data_T>
541 {
542  if (subset.isEmpty())
543  return end(subset);
544  return iterator(*this, subset, subset.min);
545 }
546 
547 //----------------------------------------------------------------------------//
548 
549 template <class Data_T>
552 {
553  return iterator(*this, base::m_dataWindow,
554  V3i(base::m_dataWindow.min.x,
555  base::m_dataWindow.min.y,
556  base::m_dataWindow.max.z + 1));
557 }
558 
559 //----------------------------------------------------------------------------//
560 
561 template <class Data_T>
564 {
565  return iterator(*this, subset,
566  V3i(subset.min.x, subset.min.y, subset.max.z + 1));
567 }
568 
569 //----------------------------------------------------------------------------//
570 
571 template <class Data_T>
573 {
574  // Call base class
575  base::sizeChanged();
576 
577  // Calculate offsets
578  m_memSize = base::m_dataWindow.max - base::m_dataWindow.min + V3i(1);
579  m_memSizeXY = m_memSize.x * m_memSize.y;
580 
581  // Check that mem size is >= 0 in all dimensions
582  if (base::m_dataWindow.max.x < base::m_dataWindow.min.x ||
583  base::m_dataWindow.max.y < base::m_dataWindow.min.y ||
584  base::m_dataWindow.max.z < base::m_dataWindow.min.z)
585  throw Exc::ResizeException("Attempt to resize ResizableField object "
586  "using negative size. Data window was: " +
587  boost::lexical_cast<std::string>(
588  base::m_dataWindow.min) + " - " +
589  boost::lexical_cast<std::string>(
590  base::m_dataWindow.max));
591 
592  // Allocate memory
593  try {
594  std::vector<Data_T>().swap(m_data);
595  m_data.resize(m_memSize.x * m_memSize.y * m_memSize.z);
596  }
597  catch (std::bad_alloc &e) {
598  throw Exc::MemoryException("Couldn't allocate DenseField of size " +
599  boost::lexical_cast<std::string>(m_memSize));
600  }
601 }
602 
603 //----------------------------------------------------------------------------//
604 
605 template <class Data_T>
606 inline Data_T* DenseField<Data_T>::ptr(int i, int j, int k)
607 {
608  // Add crop window offset
609  i -= base::m_dataWindow.min.x;
610  j -= base::m_dataWindow.min.y;
611  k -= base::m_dataWindow.min.z;
612  // Access data
613  return &m_data[i + j * m_memSize.x + k * m_memSizeXY];
614 }
615 
616 //----------------------------------------------------------------------------//
617 
618 template <class Data_T>
619 inline const Data_T* DenseField<Data_T>::ptr(int i, int j, int k) const
620 {
621  // Add crop window offset
622  i -= base::m_dataWindow.min.x;
623  j -= base::m_dataWindow.min.y;
624  k -= base::m_dataWindow.min.z;
625  // Access data
626  return &m_data[i + j * m_memSize.x + k * m_memSizeXY];
627 }
628 
629 //----------------------------------------------------------------------------//
630 // Static data member instantiation
631 //----------------------------------------------------------------------------//
632 
634 
635 //----------------------------------------------------------------------------//
636 
638 
639 //----------------------------------------------------------------------------//
640 
641 #endif // Include guard
This subclass of Field stores data in a contiguous std::vector.
Definition: DenseField.h:82
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
std::vector< Ptr > Vec
Definition: DenseField.h:90
static DEFINE_FIELD_RTTI_CONCRETE_CLASS const char * staticClassName()
Definition: DenseField.h:125
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...
Definition: DenseField.h:197
FIELD3D_VEC3_T< size_t > m_memSize
Memory allocation size in each dimension.
Definition: DenseField.h:211
std::vector< Data_T > m_data
Field storage.
Definition: DenseField.h:215
DenseField< double > DenseFieldd
Definition: DenseField.h:238
iterator begin()
Iterator to first element.
Definition: DenseField.h:530
class_type & m_field
Reference to field being iterated over.
Definition: DenseField.h:395
DenseField< V3d > DenseField3d
Definition: DenseField.h:241
LinearGenericFieldInterp< DenseField< Data_T > > LinearInterp
Definition: DenseField.h:92
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
FIELD3D_VEC3_T< T > operator*(S s, const FIELD3D_VEC3_T< T > vec)
Scalar times Vec3 multiplication. Makes the interpolation calls cleaner.
Definition: FieldInterp.h:1558
virtual std::string className() const
Returns the class name of the object. Used by the class pool and when writing the data to disk...
Definition: DenseField.h:194
virtual Data_T value(int i, int j, int k) const
Read access to a voxel. The coordinates are in integer voxel space .
Definition: DenseField.h:421
iterator end()
Iterator pointing one element past the last valid one.
Definition: DenseField.h:551
DenseField< Data_T > class_type
Definition: DenseField.h:332
const_iterator(const class_type &field, const Box3i &window, const V3i &currentPos)
Definition: DenseField.h:258
size_t m_memSizeXY
X scanline * Y scanline size.
Definition: DenseField.h:213
Imath::V3i V3i
Definition: SpiMathLib.h:71
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.
Definition: DenseField.h:186
DenseField< Data_T > class_type
Definition: DenseField.h:122
DenseField()
Constructs an empty buffer.
Definition: DenseField.h:403
Data_T * ptr(int i, int j, int k)
Returns a pointer to a given element. Used by the iterators mainly.
Definition: DenseField.h:606
static const char * classType()
Definition: DenseField.h:130
Data_T * m_p
Pointer to current element.
Definition: DenseField.h:391
const Data_T * m_p
Pointer to current element.
Definition: DenseField.h:313
ResizableField< Data_T > base
Definition: DenseField.h:95
DenseField< half > DenseFieldh
Definition: DenseField.h:236
const Data_T & fastValue(int i, int j, int k) const
Read access to voxel. Notice that this is non-virtual.
Definition: DenseField.h:447
static TemplatedFieldType< DenseField< Data_T > > ms_classType
Definition: DenseField.h:221
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.
Definition: DenseField.h:439
virtual long long int memSize() const
Returns the memory usage (in bytes)
Definition: DenseField.h:429
DenseField< Data_T > class_type
Definition: DenseField.h:254
Used to return a string for the name of a templated field.
Definition: Traits.h:116
V3i const dataResolution() const
Definition: Field.h:258
iterator(class_type &field, const Box3i &window, const V3i &currentPos)
Definition: DenseField.h:336
virtual void clear(const Data_T &value)
Clears all the voxels in the storage.
Definition: DenseField.h:413
Box3i m_window
Window to traverse.
Definition: DenseField.h:315
Contains Field, WritableField and ResizableField classes.
boost::intrusive_ptr< DenseField > Ptr
Definition: DenseField.h:89
const_iterator cbegin() const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
Definition: DenseField.h:486
DenseField< float > DenseFieldf
Definition: DenseField.h:237
DenseField< V3h > DenseField3h
Definition: DenseField.h:239
Box3i m_window
Window to traverse.
Definition: DenseField.h:393
DenseField< V3f > DenseField3f
Definition: DenseField.h:240
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: RefCount.h:81
Data_T & fastLValue(int i, int j, int k)
Write access to voxel. Notice that this is non-virtual.
Definition: DenseField.h:466
virtual void sizeChanged()
Subclasses should re-implement this if they need to perform memory allocations, etc. every time the size of the storage changes.
Definition: DenseField.h:572
const class_type & m_field
Reference to field being iterated over.
Definition: DenseField.h:317
CubicGenericFieldInterp< DenseField< Data_T > > CubicInterp
Definition: DenseField.h:93
std::string name
Optional name of the field.
Definition: Field.h:173
const_iterator cend() const
Const iterator pointing one element past the last valid one.
Definition: DenseField.h:508