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 
82 //----------------------------------------------------------------------------//
83 
84 template <class Data_T>
86  : public ResizableField<Data_T>
87 {
88 public:
89 
90  // Typedefs ------------------------------------------------------------------
91 
92  typedef boost::intrusive_ptr<DenseField> Ptr;
93  typedef std::vector<Ptr> Vec;
94 
97 
99 
100  // Constructors --------------------------------------------------------------
101 
104 
106  DenseField();
107 
108  // \}
109 
110  // Main methods --------------------------------------------------------------
111 
113  virtual void clear(const Data_T &value);
114 
115  // Threading-related ---------------------------------------------------------
116 
118  size_t numGrains() const;
120  bool getGrainBounds(const size_t idx, Box3i &vsBounds) const;
121 
122  // From Field base class -----------------------------------------------------
123 
126  virtual Data_T value(int i, int j, int k) const;
127  virtual long long int memSize() const;
129 
130  // RTTI replacement ----------------------------------------------------------
131 
134 
135  static const char *staticClassName()
136  {
137  return "DenseField";
138  }
139 
140  static const char *staticClassType()
141  {
143  }
144 
145  // From WritableField base class ---------------------------------------------
146 
149  virtual Data_T& lvalue(int i, int j, int k);
151 
152  // Concrete voxel access -----------------------------------------------------
153 
155  const Data_T& fastValue(int i, int j, int k) const;
157  Data_T& fastLValue(int i, int j, int k);
158 
159  // Iterators -----------------------------------------------------------------
160 
163 
165  class const_iterator;
166 
168  class iterator;
169 
171  const_iterator cbegin() const;
173  const_iterator cbegin(const Box3i &subset) const;
175  const_iterator cend() const;
178  const_iterator cend(const Box3i &subset) const;
180  iterator begin();
182  iterator begin(const Box3i &subset);
184  iterator end();
187  iterator end(const Box3i &subset);
188 
190 
191  // Utility methods -----------------------------------------------------------
192 
196  const FIELD3D_VEC3_T<size_t> &internalMemSize() const
197  { return m_memSize; }
198 
199  // From FieldBase ------------------------------------------------------------
200 
203 
205 
206  virtual FieldBase::Ptr clone() const
207  { return Ptr(new DenseField(*this)); }
208 
210 
211 protected:
212 
213  // From ResizableField class -------------------------------------------------
214 
215  virtual void sizeChanged();
216 
217  // Data members --------------------------------------------------------------
218 
220  FIELD3D_VEC3_T<size_t> m_memSize;
222  size_t m_memSizeXY;
224  std::vector<Data_T> m_data;
225 
226 private:
227 
228  // Static data members -------------------------------------------------------
229 
231 
232  // Direct access to memory for iterators -------------------------------------
233 
235  inline Data_T* ptr(int i, int j, int k);
237  inline const Data_T* ptr(int i, int j, int k) const;
238 
239 };
240 
241 //----------------------------------------------------------------------------//
242 // Typedefs
243 //----------------------------------------------------------------------------//
244 
251 
252 //----------------------------------------------------------------------------//
253 // DenseField::const_iterator
254 //----------------------------------------------------------------------------//
255 
256 template <class Data_T>
258 {
259 public:
260 #if defined(WIN32) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
261  typedef std::forward_iterator_tag iterator_category;
262  typedef Data_T value_type;
263  typedef ptrdiff_t difference_type;
264  typedef ptrdiff_t distance_type;
265  typedef const Data_T *pointer;
266  typedef const Data_T& reference;
267 #endif
268 
269  // Typedefs ------------------------------------------------------------------
270 
272 
273  // Constructors --------------------------------------------------------------
274 
275  const_iterator(const class_type &field, const Box3i &window,
276  const V3i &currentPos)
277  : x(currentPos.x), y(currentPos.y), z(currentPos.z),
278  m_window(window), m_field(field)
279  {
280  if (window.intersects(currentPos))
281  m_p = m_field.ptr(x, y, z);
282  else
283  m_p = 0;
284  }
285 
286  // Operators -----------------------------------------------------------------
287 
288  const const_iterator& operator ++ ()
289  {
290  if (x == m_window.max.x) {
291  if (y == m_window.max.y) {
292  if (z == m_window.max.z) {
293  m_p = 0;
294  } else {
295  m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
296  }
297  } else {
298  m_p = m_field.ptr(x = m_window.min.x, ++y, z);
299  }
300  } else {
301  ++x;
302  ++m_p;
303  }
304  return *this;
305  }
306 
307  template <class Iter_T>
308  inline bool operator == (const Iter_T &rhs) const
309  {
310  return m_p == &(*rhs);
311  }
312 
313  template <class Iter_T>
314  inline bool operator != (const Iter_T &rhs) const
315  {
316  return m_p != &(*rhs);
317  }
318 
319  inline const Data_T& operator * () const
320  {
321  return *m_p;
322  }
323 
324  inline const Data_T* operator -> () const
325  {
326  return m_p;
327  }
328 
329  // Public data members -------------------------------------------------------
330 
332  int x, y, z;
333 
334 private:
335 
336  // Private data members ------------------------------------------------------
337 
339  const Data_T *m_p;
343  const class_type &m_field;
344 
345 };
346 
347 //----------------------------------------------------------------------------//
348 // DenseField::iterator
349 //----------------------------------------------------------------------------//
350 
351 template <class Data_T>
352 class DenseField<Data_T>::iterator
353 {
354 public:
355 #if defined(WIN32) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
356  typedef std::forward_iterator_tag iterator_category;
357  typedef Data_T value_type;
358  typedef ptrdiff_t difference_type;
359  typedef ptrdiff_t distance_type;
360  typedef Data_T *pointer;
361  typedef Data_T& reference;
362 #endif
363 
364  // Typedefs ------------------------------------------------------------------
365 
367 
368  // Constructors --------------------------------------------------------------
369 
370  iterator(class_type &field, const Box3i &window,
371  const V3i &currentPos)
372  : x(currentPos.x), y(currentPos.y), z(currentPos.z),
373  m_window(window), m_field(field)
374  {
375  if (window.intersects(currentPos))
376  m_p = m_field.ptr(x, y, z);
377  else
378  m_p = 0;
379  }
380 
381  // Operators -----------------------------------------------------------------
382 
383  const iterator& operator ++ ()
384  {
385  if (x == m_window.max.x) {
386  if (y == m_window.max.y) {
387  if (z == m_window.max.z) {
388  m_p = 0;
389  } else {
390  m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
391  }
392  } else {
393  m_p = m_field.ptr(x = m_window.min.x, ++y, z);
394  }
395  } else {
396  ++x;
397  ++m_p;
398  }
399  return *this;
400  }
401 
402  template <class Iter_T>
403  inline bool operator == (const Iter_T &rhs) const
404  {
405  return m_p == &(*rhs);
406  }
407 
408  template <class Iter_T>
409  inline bool operator != (const Iter_T &rhs) const
410  {
411  return m_p != &(*rhs);
412  }
413 
414  inline Data_T& operator * () const
415  {
416  return *m_p;
417  }
418 
419  inline Data_T* operator -> () const
420  {
421  return m_p;
422  }
423 
424  // Public data members -------------------------------------------------------
425 
427  int x, y, z;
428 
429 private:
430 
431  // Private data members ------------------------------------------------------
432 
434  Data_T *m_p;
438  class_type &m_field;
439 };
440 
441 //----------------------------------------------------------------------------//
442 // DenseField implementations
443 //----------------------------------------------------------------------------//
444 
445 template <class Data_T>
447  : base(),
448  m_memSize(0), m_memSizeXY(0)
449 {
450  // Empty
451 }
452 
453 //----------------------------------------------------------------------------//
454 
455 template <class Data_T>
456 void DenseField<Data_T>::clear(const Data_T &value)
457 {
458  std::fill(m_data.begin(), m_data.end(), value);
459 }
460 
461 //----------------------------------------------------------------------------//
462 
463 template <class Data_T>
465 {
466  // Grain resolution
467  const V3i res = base::m_dataWindow.size() + V3i(1);
468  // Num grains is Y * Z
469  return res.y * res.z;
470 }
471 
472 //----------------------------------------------------------------------------//
473 
474 template <class Data_T>
475 bool DenseField<Data_T>::getGrainBounds(const size_t idx, Box3i &bounds) const
476 {
477  // Grain resolution
478  const V3i res = base::m_dataWindow.size() + V3i(1);
479  // Compute coordinate
480  const int y = idx % res.y;
481  const int z = idx / res.y;
482  // Build bbox
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);
485  bounds = Field3D::clipBounds(Box3i(start, end), base::m_dataWindow);
486  // Done
487  return true;
488 }
489 
490 //----------------------------------------------------------------------------//
491 
492 template <class Data_T>
493 Data_T DenseField<Data_T>::value(int i, int j, int k) const
494 {
495  return fastValue(i, j, k);
496 }
497 
498 //----------------------------------------------------------------------------//
499 
500 template <class Data_T>
501 long long int DenseField<Data_T>::memSize() const
502 {
503  long long int superClassMemSize = base::memSize();
504  long long int vectorMemSize = m_data.capacity() * sizeof(Data_T);
505  return sizeof(*this) + vectorMemSize + superClassMemSize;
506 }
507 
508 //----------------------------------------------------------------------------//
509 
510 template <class Data_T>
511 Data_T& DenseField<Data_T>::lvalue(int i, int j, int k)
512 {
513  return fastLValue(i, j, k);
514 }
515 
516 //----------------------------------------------------------------------------//
517 
518 template <class Data_T>
519 const Data_T& DenseField<Data_T>::fastValue(int i, int j, int k) const
520 {
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);
527  // Add crop window offset
528  i -= base::m_dataWindow.min.x;
529  j -= base::m_dataWindow.min.y;
530  k -= base::m_dataWindow.min.z;
531  // Access data
532  return m_data[i + j * m_memSize.x + k * m_memSizeXY];
533 }
534 
535 //----------------------------------------------------------------------------//
536 
537 template <class Data_T>
538 Data_T& DenseField<Data_T>::fastLValue(int i, int j, int k)
539 {
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);
546  // Add crop window offset
547  i -= base::m_dataWindow.min.x;
548  j -= base::m_dataWindow.min.y;
549  k -= base::m_dataWindow.min.z;
550  // Access data
551  return m_data[i + j * m_memSize.x + k * m_memSizeXY];
552 }
553 
554 //----------------------------------------------------------------------------//
555 
556 template <class Data_T>
559 {
560  if (FieldRes::dataResolution() == V3i(0))
561  return cend();
563 }
564 
565 //----------------------------------------------------------------------------//
566 
567 template <class Data_T>
569 DenseField<Data_T>::cbegin(const Box3i &subset) const
570 {
571  if (subset.isEmpty())
572  return cend(subset);
573  return const_iterator(*this, subset, subset.min);
574 }
575 
576 //----------------------------------------------------------------------------//
577 
578 template <class Data_T>
581 {
582  return const_iterator(*this, base::m_dataWindow,
583  V3i(base::m_dataWindow.min.x,
584  base::m_dataWindow.min.y,
585  base::m_dataWindow.max.z + 1));
586 }
587 
588 //----------------------------------------------------------------------------//
589 
590 template <class Data_T>
592 DenseField<Data_T>::cend(const Box3i &subset) const
593 {
594  return const_iterator(*this, subset,
595  V3i(subset.min.x, subset.min.y, subset.max.z + 1));
596 }
597 
598 //----------------------------------------------------------------------------//
599 
600 template <class Data_T>
603 {
604  if (FieldRes::dataResolution() == V3i(0))
605  return end();
606  return iterator(*this, base::m_dataWindow, base::m_dataWindow.min); }
607 
608 //----------------------------------------------------------------------------//
609 
610 template <class Data_T>
613 {
614  if (subset.isEmpty())
615  return end(subset);
616  return iterator(*this, subset, subset.min);
617 }
618 
619 //----------------------------------------------------------------------------//
620 
621 template <class Data_T>
624 {
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));
629 }
630 
631 //----------------------------------------------------------------------------//
632 
633 template <class Data_T>
636 {
637  return iterator(*this, subset,
638  V3i(subset.min.x, subset.min.y, subset.max.z + 1));
639 }
640 
641 //----------------------------------------------------------------------------//
642 
643 template <class Data_T>
645 {
646  // Call base class
648 
649  // Calculate offsets
652 
653  // Check that mem size is >= 0 in all dimensions
654  if (base::m_dataWindow.max.x < base::m_dataWindow.min.x ||
655  base::m_dataWindow.max.y < base::m_dataWindow.min.y ||
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));
663 
664  // Allocate memory
665  try {
666  std::vector<Data_T>().swap(m_data);
667  m_data.resize(m_memSize.x * m_memSize.y * m_memSize.z);
668  }
669  catch (std::bad_alloc &) {
670  throw Exc::MemoryException("Couldn't allocate DenseField of size " +
671  boost::lexical_cast<std::string>(m_memSize));
672  }
673 }
674 
675 //----------------------------------------------------------------------------//
676 
677 template <class Data_T>
678 inline Data_T* DenseField<Data_T>::ptr(int i, int j, int k)
679 {
680  // Add crop window offset
681  i -= base::m_dataWindow.min.x;
682  j -= base::m_dataWindow.min.y;
683  k -= base::m_dataWindow.min.z;
684  // Access data
685  return &m_data[i + j * m_memSize.x + k * m_memSizeXY];
686 }
687 
688 //----------------------------------------------------------------------------//
689 
690 template <class Data_T>
691 inline const Data_T* DenseField<Data_T>::ptr(int i, int j, int k) const
692 {
693  // Add crop window offset
694  i -= base::m_dataWindow.min.x;
695  j -= base::m_dataWindow.min.y;
696  k -= base::m_dataWindow.min.z;
697  // Access data
698  return &m_data[i + j * m_memSize.x + k * m_memSizeXY];
699 }
700 
701 //----------------------------------------------------------------------------//
702 // Static data member instantiation
703 //----------------------------------------------------------------------------//
704 
706 
707 //----------------------------------------------------------------------------//
708 
710 
711 //----------------------------------------------------------------------------//
712 
713 #endif // Include guard
This subclass of Field stores data in a contiguous std::vector.
Definition: DenseField.h:85
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
Definition: Field.h:1144
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
std::vector< Ptr > Vec
Definition: DenseField.h:93
static DEFINE_FIELD_RTTI_CONCRETE_CLASS const char * staticClassName()
Definition: DenseField.h:135
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:206
FIELD3D_VEC3_T< size_t > m_memSize
Memory allocation size in each dimension.
Definition: DenseField.h:220
std::vector< Data_T > m_data
Field storage.
Definition: DenseField.h:224
DenseField< double > DenseFieldd
Definition: DenseField.h:247
FIELD3D_CLASSNAME_CLASSTYPE_IMPLEMENTATION
Definition: DenseField.h:204
iterator begin()
Iterator to first element.
Definition: DenseField.h:602
class_type & m_field
Reference to field being iterated over.
Definition: DenseField.h:438
DenseField< V3d > DenseField3d
Definition: DenseField.h:250
LinearGenericFieldInterp< DenseField< Data_T > > LinearInterp
Definition: DenseField.h:95
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
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: Field.h:906
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
Data_T value_type
Allows us to reference the template class.
Definition: Field.h:403
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:493
iterator end()
Iterator pointing one element past the last valid one.
Definition: DenseField.h:623
Box3i m_dataWindow
Defines the area where data is allocated. This should be treated as a closed (i.e. inclusive) interval.
Definition: Field.h:315
DenseField< Data_T > class_type
Definition: DenseField.h:366
const_iterator(const class_type &field, const Box3i &window, const V3i &currentPos)
Definition: DenseField.h:275
bool getGrainBounds(const size_t idx, Box3i &vsBounds) const
Bounding box of the given &#39;grain&#39;.
Definition: DenseField.h:475
size_t m_memSizeXY
X scanline * Y scanline size.
Definition: DenseField.h:222
Imath::V3i V3i
Definition: SpiMathLib.h:71
size_t numGrains() const
Number of &#39;grains&#39; to use with threaded access.
Definition: DenseField.h:464
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:196
DenseField< Data_T > class_type
Definition: DenseField.h:132
DenseField()
Constructs an empty buffer.
Definition: DenseField.h:446
Data_T * ptr(int i, int j, int k)
Returns a pointer to a given element. Used by the iterators mainly.
Definition: DenseField.h:678
Data_T * m_p
Pointer to current element.
Definition: DenseField.h:434
const Data_T * m_p
Pointer to current element.
Definition: DenseField.h:339
static const char * staticClassType()
Definition: DenseField.h:140
ResizableField< Data_T > base
Definition: DenseField.h:98
DenseField< half > DenseFieldh
Definition: DenseField.h:245
const Data_T & fastValue(int i, int j, int k) const
Read access to voxel. Notice that this is non-virtual.
Definition: DenseField.h:519
static TemplatedFieldType< DenseField< Data_T > > ms_classType
Definition: DenseField.h:230
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:511
virtual long long int memSize() const
Returns the memory usage (in bytes)
Definition: DenseField.h:501
DenseField< Data_T > class_type
Definition: DenseField.h:271
Used to return a string for the name of a templated field.
Definition: Traits.h:116
V3i const dataResolution() const
Definition: Field.h:261
iterator(class_type &field, const Box3i &window, const V3i &currentPos)
Definition: DenseField.h:370
virtual void clear(const Data_T &value)
Clears all the voxels in the storage.
Definition: DenseField.h:456
Box3i m_window
Window to traverse.
Definition: DenseField.h:341
Contains Field, WritableField and ResizableField classes.
boost::intrusive_ptr< DenseField > Ptr
Definition: DenseField.h:92
const_iterator cbegin() const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
Definition: DenseField.h:558
DenseField< float > DenseFieldf
Definition: DenseField.h:246
DenseField< V3h > DenseField3h
Definition: DenseField.h:248
Box3i m_window
Window to traverse.
Definition: DenseField.h:436
DenseField< V3f > DenseField3f
Definition: DenseField.h:249
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: RefCount.h:84
virtual long long int memSize() const
Returns the memory usage (in bytes)
Definition: Field.h:284
Data_T & fastLValue(int i, int j, int k)
Write access to voxel. Notice that this is non-virtual.
Definition: DenseField.h:538
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:644
const class_type & m_field
Reference to field being iterated over.
Definition: DenseField.h:343
CubicGenericFieldInterp< DenseField< Data_T > > CubicInterp
Definition: DenseField.h:96
std::string name
Optional name of the field.
Definition: Field.h:176
const_iterator cend() const
Const iterator pointing one element past the last valid one.
Definition: DenseField.h:580