Field3D
DenseField.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------//
00002 
00003 /*
00004  * Copyright (c) 2009 Sony Pictures Imageworks Inc
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  *
00012  * Redistributions of source code must retain the above copyright
00013  * notice, this list of conditions and the following disclaimer.
00014  * Redistributions in binary form must reproduce the above copyright
00015  * notice, this list of conditions and the following disclaimer in the
00016  * documentation and/or other materials provided with the
00017  * distribution.  Neither the name of Sony Pictures Imageworks nor the
00018  * names of its contributors may be used to endorse or promote
00019  * products derived from this software without specific prior written
00020  * permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
00026  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00029  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00031  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00033  * OF THE POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 //----------------------------------------------------------------------------//
00037 
00042 //----------------------------------------------------------------------------//
00043 
00044 #ifndef _INCLUDED_Field3D_DenseField_H_
00045 #define _INCLUDED_Field3D_DenseField_H_
00046 
00047 #include <vector>
00048 
00049 #include <boost/lexical_cast.hpp>
00050 
00051 #include "Field.h"
00052 
00053 //----------------------------------------------------------------------------//
00054 
00055 #include "ns.h"
00056 
00057 FIELD3D_NAMESPACE_OPEN
00058 
00059 //----------------------------------------------------------------------------//
00060 // Forward declarations 
00061 //----------------------------------------------------------------------------//
00062 
00063 template <class Field_T>
00064 class LinearGenericFieldInterp;
00065 template <class Field_T>
00066 class CubicGenericFieldInterp; 
00067 
00068 //----------------------------------------------------------------------------//
00069 // DenseField
00070 //----------------------------------------------------------------------------//
00071 
00079 //----------------------------------------------------------------------------//
00080 
00081 template <class Data_T>
00082 class DenseField
00083   : public ResizableField<Data_T>
00084 {
00085 public:
00086 
00087   // Typedefs ------------------------------------------------------------------
00088   
00089   typedef boost::intrusive_ptr<DenseField> Ptr;
00090   typedef std::vector<Ptr> Vec;
00091 
00092   typedef LinearGenericFieldInterp<DenseField<Data_T> > LinearInterp;
00093   typedef CubicGenericFieldInterp<DenseField<Data_T> > CubicInterp;
00094 
00095   typedef ResizableField<Data_T> base;
00096 
00097   // Constructors --------------------------------------------------------------
00098 
00101 
00103   DenseField();
00104 
00105   // \}
00106 
00107   // Main methods --------------------------------------------------------------
00108 
00110   virtual void clear(const Data_T &value);
00111 
00112   // From Field base class -----------------------------------------------------
00113 
00116   virtual Data_T value(int i, int j, int k) const;
00117   virtual long long int memSize() const;
00119 
00120   // RTTI replacement ----------------------------------------------------------
00121 
00122   typedef DenseField<Data_T> class_type;
00123   DEFINE_FIELD_RTTI_CONCRETE_CLASS
00124 
00125   static const char *staticClassName()
00126   {
00127     return "DenseField";
00128   }
00129 
00130   static const char *classType()
00131   {
00132     return DenseField<Data_T>::ms_classType.name();
00133   } 
00134     
00135   // From WritableField base class ---------------------------------------------
00136 
00139   virtual Data_T& lvalue(int i, int j, int k);
00141   
00142   // Concrete voxel access -----------------------------------------------------
00143 
00145   const Data_T& fastValue(int i, int j, int k) const;
00147   Data_T& fastLValue(int i, int j, int k);
00148 
00149   // Iterators -----------------------------------------------------------------
00150 
00153 
00155   class const_iterator;
00156 
00158   class iterator;
00159 
00161   const_iterator cbegin() const;
00163   const_iterator cbegin(const Box3i &subset) const;
00165   const_iterator cend() const;
00168   const_iterator cend(const Box3i &subset) const;
00170   iterator begin();
00172   iterator begin(const Box3i &subset);
00174   iterator end();
00177   iterator end(const Box3i &subset);
00178 
00180 
00181   // Utility methods -----------------------------------------------------------
00182 
00186   const FIELD3D_VEC3_T<size_t> &internalMemSize() const
00187   { return m_memSize; }
00188 
00189   // From FieldBase ------------------------------------------------------------
00190 
00193 
00194   virtual std::string className() const
00195   { return staticClassName(); }
00196   
00197   virtual FieldBase::Ptr clone() const
00198   { return Ptr(new DenseField(*this)); }
00199 
00201 
00202 protected:
00203 
00204   // From ResizableField class -------------------------------------------------
00205 
00206   virtual void sizeChanged();
00207 
00208   // Data members --------------------------------------------------------------
00209 
00211   FIELD3D_VEC3_T<size_t> m_memSize;
00213   size_t m_memSizeXY;
00215   std::vector<Data_T> m_data;
00216 
00217 private:
00218 
00219   // Static data members -------------------------------------------------------
00220 
00221   static TemplatedFieldType<DenseField<Data_T> > ms_classType;
00222 
00223   // Direct access to memory for iterators -------------------------------------
00224 
00226   inline Data_T* ptr(int i, int j, int k);
00228   inline const Data_T* ptr(int i, int j, int k) const;
00229 
00230 };
00231 
00232 //----------------------------------------------------------------------------//
00233 // Typedefs
00234 //----------------------------------------------------------------------------//
00235 
00236 typedef DenseField<half>   DenseFieldh;
00237 typedef DenseField<float>  DenseFieldf;
00238 typedef DenseField<double> DenseFieldd;
00239 typedef DenseField<V3h>    DenseField3h;
00240 typedef DenseField<V3f>    DenseField3f;
00241 typedef DenseField<V3d>    DenseField3d;
00242 
00243 //----------------------------------------------------------------------------//
00244 // DenseField::const_iterator
00245 //----------------------------------------------------------------------------//
00246 
00247 template <class Data_T>
00248 class DenseField<Data_T>::const_iterator
00249 {
00250 public:
00251 
00252   // Typedefs ------------------------------------------------------------------
00253 
00254   typedef DenseField<Data_T> class_type;
00255 
00256   // Constructors --------------------------------------------------------------
00257 
00258   const_iterator(const class_type &field, const Box3i &window,
00259                  const V3i &currentPos)
00260     : x(currentPos.x), y(currentPos.y), z(currentPos.z), 
00261       m_window(window), m_field(field)
00262   { m_p = m_field.ptr(x, y, z); }
00263 
00264   // Operators -----------------------------------------------------------------
00265 
00266   const const_iterator& operator ++ ()
00267   {
00268     if (x == m_window.max.x) {
00269       if (y == m_window.max.y) {
00270         m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
00271       } else {
00272         m_p = m_field.ptr(x = m_window.min.x, ++y, z);
00273       }
00274     } else {
00275       ++x;
00276       ++m_p;
00277     }
00278     return *this;
00279   }
00280 
00281   template <class Iter_T>
00282   inline bool operator == (const Iter_T &rhs) const
00283   {
00284     return m_p == &(*rhs);
00285   }
00286 
00287   template <class Iter_T>
00288   inline bool operator != (const Iter_T &rhs) const
00289   {
00290     return m_p != &(*rhs);
00291   }
00292 
00293   inline const Data_T& operator * () const
00294   {
00295     return *m_p;
00296   }
00297 
00298   inline const Data_T* operator -> () const
00299   {
00300     return m_p;
00301   }
00302 
00303   // Public data members -------------------------------------------------------
00304 
00306   int x, y, z;
00307 
00308 private:
00309 
00310   // Private data members ------------------------------------------------------
00311 
00313   const Data_T *m_p;
00315   Box3i m_window;
00317   const class_type &m_field;
00318 
00319 };
00320 
00321 //----------------------------------------------------------------------------//
00322 // DenseField::iterator
00323 //----------------------------------------------------------------------------//
00324 
00325 template <class Data_T>
00326 class DenseField<Data_T>::iterator
00327 {
00328 public:
00329 
00330   // Typedefs ------------------------------------------------------------------
00331 
00332   typedef DenseField<Data_T> class_type;
00333 
00334   // Constructors --------------------------------------------------------------
00335 
00336   iterator(class_type &field, const Box3i &window,
00337            const V3i &currentPos)
00338     : x(currentPos.x), y(currentPos.y), z(currentPos.z), 
00339       m_window(window), m_field(field)
00340   { m_p = m_field.ptr(x, y, z); }
00341 
00342   // Operators -----------------------------------------------------------------
00343 
00344   const iterator& operator ++ ()
00345   {
00346     if (x == m_window.max.x) {
00347       if (y == m_window.max.y) {
00348         m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
00349       } else {
00350         m_p = m_field.ptr(x = m_window.min.x, ++y, z);
00351       }
00352     } else {
00353       ++x;
00354       ++m_p;
00355     }
00356     return *this;
00357   }
00358 
00359   template <class Iter_T>
00360   inline bool operator == (const Iter_T &rhs) const
00361   {
00362     return m_p == &(*rhs);
00363   }
00364 
00365   template <class Iter_T>
00366   inline bool operator != (const Iter_T &rhs) const
00367   {
00368     return m_p != &(*rhs);
00369   }
00370 
00371   inline Data_T& operator * () const
00372   {
00373     return *m_p;
00374   }
00375 
00376   inline Data_T* operator -> () const
00377   {
00378     return m_p;
00379   }
00380 
00381   // Public data members -------------------------------------------------------
00382 
00384   int x, y, z;
00385 
00386 private:
00387 
00388   // Private data members ------------------------------------------------------
00389 
00391   Data_T *m_p;
00393   Box3i m_window;
00395   class_type &m_field;
00396 };
00397 
00398 //----------------------------------------------------------------------------//
00399 // DenseField implementations
00400 //----------------------------------------------------------------------------//
00401 
00402 template <class Data_T>
00403 DenseField<Data_T>::DenseField()
00404   : base(),
00405     m_memSize(0), m_memSizeXY(0)
00406 {
00407   // Empty
00408 }
00409 
00410 //----------------------------------------------------------------------------//
00411 
00412 template <class Data_T>
00413 void DenseField<Data_T>::clear(const Data_T &value)
00414 {
00415   std::fill(m_data.begin(), m_data.end(), value);
00416 }
00417 
00418 //----------------------------------------------------------------------------//
00419 
00420 template <class Data_T>
00421 Data_T DenseField<Data_T>::value(int i, int j, int k) const
00422 {
00423   return fastValue(i, j, k);
00424 }
00425 
00426 //----------------------------------------------------------------------------//
00427 
00428 template <class Data_T>
00429 long long int DenseField<Data_T>::memSize() const
00430 { 
00431   long long int superClassMemSize = base::memSize();
00432   long long int vectorMemSize = m_data.capacity() * sizeof(Data_T);
00433   return sizeof(*this) + vectorMemSize + superClassMemSize; 
00434 }
00435 
00436 //----------------------------------------------------------------------------//
00437 
00438 template <class Data_T>
00439 Data_T& DenseField<Data_T>::lvalue(int i, int j, int k)
00440 {
00441   return fastLValue(i, j, k);
00442 }
00443 
00444 //----------------------------------------------------------------------------//
00445 
00446 template <class Data_T>
00447 const Data_T& DenseField<Data_T>::fastValue(int i, int j, int k) const
00448 {
00449   assert (i >= base::m_dataWindow.min.x);
00450   assert (i <= base::m_dataWindow.max.x);
00451   assert (j >= base::m_dataWindow.min.y);
00452   assert (j <= base::m_dataWindow.max.y);
00453   assert (k >= base::m_dataWindow.min.z);
00454   assert (k <= base::m_dataWindow.max.z);
00455   // Add crop window offset
00456   i -= base::m_dataWindow.min.x;
00457   j -= base::m_dataWindow.min.y;
00458   k -= base::m_dataWindow.min.z;
00459   // Access data
00460   return m_data[i + j * m_memSize.x + k * m_memSizeXY];
00461 }
00462 
00463 //----------------------------------------------------------------------------//
00464 
00465 template <class Data_T>
00466 Data_T& DenseField<Data_T>::fastLValue(int i, int j, int k)
00467 {
00468   assert (i >= base::m_dataWindow.min.x);
00469   assert (i <= base::m_dataWindow.max.x);
00470   assert (j >= base::m_dataWindow.min.y);
00471   assert (j <= base::m_dataWindow.max.y);
00472   assert (k >= base::m_dataWindow.min.z);
00473   assert (k <= base::m_dataWindow.max.z);
00474   // Add crop window offset
00475   i -= base::m_dataWindow.min.x;
00476   j -= base::m_dataWindow.min.y;
00477   k -= base::m_dataWindow.min.z;
00478   // Access data
00479   return m_data[i + j * m_memSize.x + k * m_memSizeXY];
00480 }
00481 
00482 //----------------------------------------------------------------------------//
00483 
00484 template <class Data_T>
00485 typename DenseField<Data_T>::const_iterator 
00486 DenseField<Data_T>::cbegin() const
00487 { 
00488   if (FieldRes::dataResolution() == V3i(0))
00489     return cend();
00490   return const_iterator(*this, base::m_dataWindow, base::m_dataWindow.min); 
00491 }
00492 
00493 //----------------------------------------------------------------------------//
00494 
00495 template <class Data_T>
00496 typename DenseField<Data_T>::const_iterator 
00497 DenseField<Data_T>::cbegin(const Box3i &subset) const
00498 { 
00499   if (subset.isEmpty())
00500     return cend(subset);
00501   return const_iterator(*this, subset, subset.min); 
00502 }
00503 
00504 //----------------------------------------------------------------------------//
00505 
00506 template <class Data_T>
00507 typename DenseField<Data_T>::const_iterator 
00508 DenseField<Data_T>::cend() const
00509 { 
00510   return const_iterator(*this, base::m_dataWindow, 
00511                         V3i(base::m_dataWindow.min.x, 
00512                             base::m_dataWindow.min.y,
00513                             base::m_dataWindow.max.z + 1));
00514 }
00515 
00516 //----------------------------------------------------------------------------//
00517 
00518 template <class Data_T>
00519 typename DenseField<Data_T>::const_iterator 
00520 DenseField<Data_T>::cend(const Box3i &subset) const
00521 { 
00522   return const_iterator(*this, subset, 
00523                         V3i(subset.min.x, subset.min.y, subset.max.z + 1));
00524 }
00525 
00526 //----------------------------------------------------------------------------//
00527 
00528 template <class Data_T>
00529 typename DenseField<Data_T>::iterator 
00530 DenseField<Data_T>::begin()
00531 { 
00532   if (FieldRes::dataResolution() == V3i(0))
00533     return end();
00534   return iterator(*this, base::m_dataWindow, base::m_dataWindow.min); }
00535 
00536 //----------------------------------------------------------------------------//
00537 
00538 template <class Data_T>
00539 typename DenseField<Data_T>::iterator 
00540 DenseField<Data_T>::begin(const Box3i &subset)
00541 { 
00542   if (subset.isEmpty())
00543     return end(subset);
00544   return iterator(*this, subset, subset.min); 
00545 }
00546 
00547 //----------------------------------------------------------------------------//
00548 
00549 template <class Data_T>
00550 typename DenseField<Data_T>::iterator 
00551 DenseField<Data_T>::end()
00552 { 
00553   return iterator(*this, base::m_dataWindow, 
00554                   V3i(base::m_dataWindow.min.x, 
00555                       base::m_dataWindow.min.y,
00556                       base::m_dataWindow.max.z + 1));
00557 }
00558 
00559 //----------------------------------------------------------------------------//
00560 
00561 template <class Data_T>
00562 typename DenseField<Data_T>::iterator 
00563 DenseField<Data_T>::end(const Box3i &subset)
00564 { 
00565   return iterator(*this, subset, 
00566                   V3i(subset.min.x, subset.min.y, subset.max.z + 1));
00567 }
00568 
00569 //----------------------------------------------------------------------------//
00570 
00571 template <class Data_T>
00572 void DenseField<Data_T>::sizeChanged() 
00573 {
00574   // Call base class
00575   base::sizeChanged();
00576 
00577   // Calculate offsets
00578   m_memSize = base::m_dataWindow.max - base::m_dataWindow.min + V3i(1);
00579   m_memSizeXY = m_memSize.x * m_memSize.y;
00580 
00581   // Check that mem size is >= 0 in all dimensions
00582   if (base::m_dataWindow.max.x < base::m_dataWindow.min.x ||
00583       base::m_dataWindow.max.y < base::m_dataWindow.min.y ||
00584       base::m_dataWindow.max.z < base::m_dataWindow.min.z)
00585     throw Exc::ResizeException("Attempt to resize ResizableField object "
00586                                "using negative size. Data window was: " +
00587                                boost::lexical_cast<std::string>(
00588                                  base::m_dataWindow.min) + " - " +
00589                                boost::lexical_cast<std::string>(
00590                                  base::m_dataWindow.max));
00591 
00592   // Allocate memory
00593   try {
00594     std::vector<Data_T>().swap(m_data);
00595     m_data.resize(m_memSize.x * m_memSize.y * m_memSize.z);
00596   }
00597   catch (std::bad_alloc &e) {
00598     throw Exc::MemoryException("Couldn't allocate DenseField of size " + 
00599                                boost::lexical_cast<std::string>(m_memSize));
00600   }
00601 }
00602 
00603 //----------------------------------------------------------------------------//
00604 
00605 template <class Data_T>
00606 inline Data_T* DenseField<Data_T>::ptr(int i, int j, int k)
00607 {
00608   // Add crop window offset
00609   i -= base::m_dataWindow.min.x;
00610   j -= base::m_dataWindow.min.y;
00611   k -= base::m_dataWindow.min.z;
00612   // Access data
00613   return &m_data[i + j * m_memSize.x + k * m_memSizeXY];      
00614 }
00615 
00616 //----------------------------------------------------------------------------//
00617 
00618 template <class Data_T>
00619 inline const Data_T* DenseField<Data_T>::ptr(int i, int j, int k) const
00620 {
00621   // Add crop window offset
00622   i -= base::m_dataWindow.min.x;
00623   j -= base::m_dataWindow.min.y;
00624   k -= base::m_dataWindow.min.z;
00625   // Access data
00626   return &m_data[i + j * m_memSize.x + k * m_memSizeXY];
00627 }
00628 
00629 //----------------------------------------------------------------------------//
00630 // Static data member instantiation
00631 //----------------------------------------------------------------------------//
00632 
00633 FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(DenseField);
00634 
00635 //----------------------------------------------------------------------------//
00636 
00637 FIELD3D_NAMESPACE_HEADER_CLOSE
00638 
00639 //----------------------------------------------------------------------------//
00640 
00641 #endif // Include guard