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
63template <class Field_T>
65template <class Field_T>
67
68//----------------------------------------------------------------------------//
69// DenseField
70//----------------------------------------------------------------------------//
71
82//----------------------------------------------------------------------------//
83
84template <class Data_T>
86 : public ResizableField<Data_T>
87{
88public:
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
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
211protected:
212
213 // From ResizableField class -------------------------------------------------
214
215 virtual void sizeChanged();
216
217 // Data members --------------------------------------------------------------
218
224 std::vector<Data_T> m_data;
225
226private:
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
256template <class Data_T>
258{
259public:
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
334private:
335
336 // Private data members ------------------------------------------------------
337
339 const Data_T *m_p;
344
345};
346
347//----------------------------------------------------------------------------//
348// DenseField::iterator
349//----------------------------------------------------------------------------//
350
351template <class Data_T>
352class DenseField<Data_T>::iterator
353{
354public:
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
429private:
430
431 // Private data members ------------------------------------------------------
432
434 Data_T *m_p;
439};
440
441//----------------------------------------------------------------------------//
442// DenseField implementations
443//----------------------------------------------------------------------------//
444
445template <class Data_T>
447 : base(),
448 m_memSize(0), m_memSizeXY(0)
449{
450 // Empty
451}
452
453//----------------------------------------------------------------------------//
454
455template <class Data_T>
456void DenseField<Data_T>::clear(const Data_T &value)
457{
458 std::fill(m_data.begin(), m_data.end(), value);
459}
460
461//----------------------------------------------------------------------------//
462
463template <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
474template <class Data_T>
475bool 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
492template <class Data_T>
493Data_T DenseField<Data_T>::value(int i, int j, int k) const
494{
495 return fastValue(i, j, k);
496}
497
498//----------------------------------------------------------------------------//
499
500template <class Data_T>
501long 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
510template <class Data_T>
511Data_T& DenseField<Data_T>::lvalue(int i, int j, int k)
512{
513 return fastLValue(i, j, k);
514}
515
516//----------------------------------------------------------------------------//
517
518template <class Data_T>
519const 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
537template <class Data_T>
538Data_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
556template <class Data_T>
559{
560 if (FieldRes::dataResolution() == V3i(0))
561 return cend();
562 return const_iterator(*this, base::m_dataWindow, base::m_dataWindow.min);
563}
564
565//----------------------------------------------------------------------------//
566
567template <class Data_T>
570{
571 if (subset.isEmpty())
572 return cend(subset);
573 return const_iterator(*this, subset, subset.min);
574}
575
576//----------------------------------------------------------------------------//
577
578template <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
590template <class Data_T>
592DenseField<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
600template <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
610template <class Data_T>
613{
614 if (subset.isEmpty())
615 return end(subset);
616 return iterator(*this, subset, subset.min);
617}
618
619//----------------------------------------------------------------------------//
620
621template <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
633template <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
643template <class Data_T>
645{
646 // Call base class
647 base::sizeChanged();
648
649 // Calculate offsets
650 m_memSize = base::m_dataWindow.max - base::m_dataWindow.min + V3i(1);
651 m_memSizeXY = m_memSize.x * m_memSize.y;
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 ||
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));
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
677template <class Data_T>
678inline 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
690template <class Data_T>
691inline 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
DenseField< V3d > DenseField3d
Definition DenseField.h:250
DenseField< float > DenseFieldf
Definition DenseField.h:246
DenseField< V3h > DenseField3h
Definition DenseField.h:248
DenseField< half > DenseFieldh
Definition DenseField.h:245
DenseField< V3f > DenseField3f
Definition DenseField.h:249
DenseField< double > DenseFieldd
Definition DenseField.h:247
FIELD3D_VEC3_T< T > operator*(S s, const FIELD3D_VEC3_T< T > vec)
Scalar times Vec3 multiplication. Makes the interpolation calls cleaner.
Contains Field, WritableField and ResizableField classes.
#define FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(field)
Definition Field.h:479
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition RefCount.h:84
Imath::V3i V3i
Definition SpiMathLib.h:71
#define FIELD3D_VEC3_T
Definition SpiMathLib.h:88
Imath::Box3i Box3i
Definition SpiMathLib.h:77
int x
Current position.
Definition DenseField.h:332
const Data_T * m_p
Pointer to current element.
Definition DenseField.h:339
const_iterator(const class_type &field, const Box3i &window, const V3i &currentPos)
Definition DenseField.h:275
const class_type & m_field
Reference to field being iterated over.
Definition DenseField.h:343
Box3i m_window
Window to traverse.
Definition DenseField.h:341
DenseField< Data_T > class_type
Definition DenseField.h:271
int x
Current position.
Definition DenseField.h:427
Data_T * m_p
Pointer to current element.
Definition DenseField.h:434
DenseField< Data_T > class_type
Definition DenseField.h:366
class_type & m_field
Reference to field being iterated over.
Definition DenseField.h:438
iterator(class_type &field, const Box3i &window, const V3i &currentPos)
Definition DenseField.h:370
Box3i m_window
Window to traverse.
Definition DenseField.h:436
This subclass of Field stores data in a contiguous std::vector.
Definition DenseField.h:87
boost::intrusive_ptr< DenseField > Ptr
Definition DenseField.h:92
virtual long long int memSize() const
Returns the memory usage (in bytes)
Definition DenseField.h:501
iterator end()
Iterator pointing one element past the last valid one.
Definition DenseField.h:623
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
std::vector< Data_T > m_data
Field storage.
Definition DenseField.h:224
virtual Data_T & lvalue(int i, int j, int k)
Write access to a voxel. The coordinates are global coordinates.
Definition DenseField.h:511
Data_T & fastLValue(int i, int j, int k)
Write access to voxel. Notice that this is non-virtual.
Definition DenseField.h:538
size_t m_memSizeXY
X scanline * Y scanline size.
Definition DenseField.h:222
DenseField()
Constructs an empty buffer.
Definition DenseField.h:446
virtual void clear(const Data_T &value)
Clears all the voxels in the storage.
Definition DenseField.h:456
FIELD3D_CLASSNAME_CLASSTYPE_IMPLEMENTATION
Definition DenseField.h:204
ResizableField< Data_T > base
Definition DenseField.h:98
const_iterator cbegin() const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
Definition DenseField.h:558
const_iterator cend() const
Const iterator pointing one element past the last valid one.
Definition DenseField.h:580
const FIELD3D_VEC3_T< size_t > & internalMemSize() const
Returns the internal memory size in each dimension. This is used for example in LinearInterpolator,...
Definition DenseField.h:196
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
iterator begin()
Iterator to first element.
Definition DenseField.h:602
DenseField< Data_T > class_type
Definition DenseField.h:132
bool getGrainBounds(const size_t idx, Box3i &vsBounds) const
Bounding box of the given 'grain'.
Definition DenseField.h:475
virtual void sizeChanged()
Subclasses should re-implement this if they need to perform memory allocations, etc....
Definition DenseField.h:644
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
static DEFINE_FIELD_RTTI_CONCRETE_CLASS const char * staticClassName()
Definition DenseField.h:135
static TemplatedFieldType< DenseField< Data_T > > ms_classType
Definition DenseField.h:230
size_t numGrains() const
Number of 'grains' to use with threaded access.
Definition DenseField.h:464
FIELD3D_VEC3_T< size_t > m_memSize
Memory allocation size in each dimension.
Definition DenseField.h:220
std::vector< Ptr > Vec
Definition DenseField.h:93
LinearGenericFieldInterp< DenseField< Data_T > > LinearInterp
Definition DenseField.h:95
static const char * staticClassType()
Definition DenseField.h:140
CubicGenericFieldInterp< DenseField< Data_T > > CubicInterp
Definition DenseField.h:96
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
boost::intrusive_ptr< FieldBase > Ptr
Definition Field.h:97
std::string name
Optional name of the field.
Definition Field.h:171
V3i const dataResolution() const
Definition Field.h:256
Data_T value_type
Allows us to reference the template class.
Definition Field.h:398
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition ns.h:58
Used to return a string for the name of a templated field.
Definition Traits.h:283