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 //----------------------------------------------------------------------------//
00070 // DenseField
00071 //----------------------------------------------------------------------------//
00072 
00080 //----------------------------------------------------------------------------//
00081 
00082 template <class Data_T>
00083 class DenseField
00084   : public ResizableField<Data_T>
00085 {
00086 public:
00087 
00088   // Typedefs ------------------------------------------------------------------
00089   
00090   typedef boost::intrusive_ptr<DenseField> Ptr;
00091   typedef std::vector<Ptr> Vec;
00092 
00093   typedef LinearGenericFieldInterp<DenseField<Data_T> > LinearInterp;
00094   typedef CubicGenericFieldInterp<DenseField<Data_T> > CubicInterp;
00095 
00096   typedef ResizableField<Data_T> base;
00097 
00098   // Constructors --------------------------------------------------------------
00099 
00102 
00104   DenseField();
00105 
00106   // \}
00107 
00108   // Main methods --------------------------------------------------------------
00109 
00111   virtual void clear(const Data_T &value);
00112 
00113   // From Field base class -----------------------------------------------------
00114 
00117   virtual Data_T value(int i, int j, int k) const;
00118   virtual long long int memSize() const;
00120 
00121   // RTTI replacement ----------------------------------------------------------
00122 
00123   typedef DenseField<Data_T> class_type;
00124   DEFINE_FIELD_RTTI_CONCRETE_CLASS
00125 
00126   // From WritableField base class ---------------------------------------------
00127 
00130   virtual Data_T& lvalue(int i, int j, int k);
00132   
00133   // Concrete voxel access -----------------------------------------------------
00134 
00136   const Data_T& fastValue(int i, int j, int k) const;
00138   Data_T& fastLValue(int i, int j, int k);
00139 
00140   // Iterators -----------------------------------------------------------------
00141 
00144 
00146   class const_iterator;
00147 
00149   class iterator;
00150 
00152   const_iterator cbegin() const;
00154   const_iterator cbegin(const Box3i &subset) const;
00156   const_iterator cend() const;
00159   const_iterator cend(const Box3i &subset) const;
00161   iterator begin();
00163   iterator begin(const Box3i &subset);
00165   iterator end();
00168   iterator end(const Box3i &subset);
00169 
00171 
00172   // Utility methods -----------------------------------------------------------
00173 
00177   const FIELD3D_VEC3_T<size_t> &internalMemSize() const
00178   { return m_memSize; }
00179 
00180   // From FieldBase ------------------------------------------------------------
00181 
00184   virtual std::string className() const
00185   { return std::string("DenseField"); }
00186 
00187   virtual FieldBase::Ptr clone() const
00188   { return Ptr(new DenseField(*this)); }
00189 
00191 
00192  protected:
00193 
00194   // From ResizableField class ---------------------------------------------
00195 
00196   virtual void sizeChanged();
00197 
00198   // Data members --------------------------------------------------------------
00199 
00201   FIELD3D_VEC3_T<size_t> m_memSize;
00203   size_t m_memSizeXY;
00205   std::vector<Data_T> m_data;
00206 
00207  private:
00208 
00209   // Direct access to memory for iterators -------------------------------------
00210 
00212   inline Data_T* ptr(int i, int j, int k);
00214   inline const Data_T* ptr(int i, int j, int k) const;
00215 
00216 };
00217 
00218 //----------------------------------------------------------------------------//
00219 // Typedefs
00220 //----------------------------------------------------------------------------//
00221 
00222 typedef DenseField<half>   DenseFieldh;
00223 typedef DenseField<float>  DenseFieldf;
00224 typedef DenseField<double> DenseFieldd;
00225 typedef DenseField<V3h>    DenseField3h;
00226 typedef DenseField<V3f>    DenseField3f;
00227 typedef DenseField<V3d>    DenseField3d;
00228 
00229 //----------------------------------------------------------------------------//
00230 // DenseField::const_iterator
00231 //----------------------------------------------------------------------------//
00232 
00233 template <class Data_T>
00234 class DenseField<Data_T>::const_iterator
00235 {
00236 public:
00237 
00238   // Typedefs ------------------------------------------------------------------
00239 
00240   typedef DenseField<Data_T> class_type;
00241 
00242   // Constructors --------------------------------------------------------------
00243 
00244   const_iterator(const class_type &field, const Box3i &window,
00245                  const V3i &currentPos)
00246     : x(currentPos.x), y(currentPos.y), z(currentPos.z), 
00247       m_window(window), m_field(field)
00248   { m_p = m_field.ptr(x, y, z); }
00249 
00250   // Operators -----------------------------------------------------------------
00251 
00252   const const_iterator& operator ++ ()
00253   {
00254     if (x == m_window.max.x) {
00255       if (y == m_window.max.y) {
00256         m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
00257       } else {
00258         m_p = m_field.ptr(x = m_window.min.x, ++y, z);
00259       }
00260     } else {
00261       ++x;
00262       ++m_p;
00263     }
00264     return *this;
00265   }
00266 
00267   template <class Iter_T>
00268   inline bool operator == (const Iter_T &rhs) const
00269   {
00270     return m_p == &(*rhs);
00271   }
00272 
00273   template <class Iter_T>
00274   inline bool operator != (const Iter_T &rhs) const
00275   {
00276     return m_p != &(*rhs);
00277   }
00278 
00279   inline const Data_T& operator * () const
00280   {
00281     return *m_p;
00282   }
00283 
00284   inline const Data_T* operator -> () const
00285   {
00286     return m_p;
00287   }
00288 
00289   // Public data members -------------------------------------------------------
00290 
00292   int x, y, z;
00293 
00294 private:
00295 
00296   // Private data members ------------------------------------------------------
00297 
00299   const Data_T *m_p;
00301   Box3i m_window;
00303   const class_type &m_field;
00304 
00305 };
00306 
00307 //----------------------------------------------------------------------------//
00308 // DenseField::iterator
00309 //----------------------------------------------------------------------------//
00310 
00311 template <class Data_T>
00312 class DenseField<Data_T>::iterator
00313 {
00314 public:
00315 
00316   // Typedefs ------------------------------------------------------------------
00317 
00318   typedef DenseField<Data_T> class_type;
00319 
00320   // Constructors --------------------------------------------------------------
00321 
00322   iterator(class_type &field, const Box3i &window,
00323            const V3i &currentPos)
00324     : x(currentPos.x), y(currentPos.y), z(currentPos.z), 
00325       m_window(window), m_field(field)
00326   { m_p = m_field.ptr(x, y, z); }
00327 
00328   // Operators -----------------------------------------------------------------
00329 
00330   const iterator& operator ++ ()
00331   {
00332     if (x == m_window.max.x) {
00333       if (y == m_window.max.y) {
00334         m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
00335       } else {
00336         m_p = m_field.ptr(x = m_window.min.x, ++y, z);
00337       }
00338     } else {
00339       ++x;
00340       ++m_p;
00341     }
00342     return *this;
00343   }
00344 
00345   template <class Iter_T>
00346   inline bool operator == (const Iter_T &rhs) const
00347   {
00348     return m_p == &(*rhs);
00349   }
00350 
00351   template <class Iter_T>
00352   inline bool operator != (const Iter_T &rhs) const
00353   {
00354     return m_p != &(*rhs);
00355   }
00356 
00357   inline Data_T& operator * () const
00358   {
00359     return *m_p;
00360   }
00361 
00362   inline Data_T* operator -> () const
00363   {
00364     return m_p;
00365   }
00366 
00367   // Public data members -------------------------------------------------------
00368 
00370   int x, y, z;
00371 
00372 private:
00373 
00374   // Private data members ------------------------------------------------------
00375 
00377   Data_T *m_p;
00379   Box3i m_window;
00381   class_type &m_field;
00382 };
00383 
00384 //----------------------------------------------------------------------------//
00385 // DenseField implementations
00386 //----------------------------------------------------------------------------//
00387 
00388 template <class Data_T>
00389 DenseField<Data_T>::DenseField()
00390   : base(),
00391     m_memSize(0), m_memSizeXY(0)
00392 {
00393   // Empty
00394 }
00395 
00396 //----------------------------------------------------------------------------//
00397 
00398 template <class Data_T>
00399 void DenseField<Data_T>::clear(const Data_T &value)
00400 {
00401   std::fill(m_data.begin(), m_data.end(), value);
00402 }
00403 
00404 //----------------------------------------------------------------------------//
00405 
00406 template <class Data_T>
00407 Data_T DenseField<Data_T>::value(int i, int j, int k) const
00408 {
00409   return fastValue(i, j, k);
00410 }
00411 
00412 //----------------------------------------------------------------------------//
00413 
00414 template <class Data_T>
00415 long long int DenseField<Data_T>::memSize() const
00416 { 
00417   long long int superClassMemSize = base::memSize();
00418   long long int vectorMemSize = m_data.capacity() * sizeof(Data_T);
00419   return sizeof(*this) + vectorMemSize + superClassMemSize; 
00420 }
00421 
00422 //----------------------------------------------------------------------------//
00423 
00424 template <class Data_T>
00425 Data_T& DenseField<Data_T>::lvalue(int i, int j, int k)
00426 {
00427   return fastLValue(i, j, k);
00428 }
00429 
00430 //----------------------------------------------------------------------------//
00431 
00432 template <class Data_T>
00433 const Data_T& DenseField<Data_T>::fastValue(int i, int j, int k) const
00434 {
00435   assert (i >= base::m_dataWindow.min.x);
00436   assert (i <= base::m_dataWindow.max.x);
00437   assert (j >= base::m_dataWindow.min.y);
00438   assert (j <= base::m_dataWindow.max.y);
00439   assert (k >= base::m_dataWindow.min.z);
00440   assert (k <= base::m_dataWindow.max.z);
00441   // Add crop window offset
00442   i -= base::m_dataWindow.min.x;
00443   j -= base::m_dataWindow.min.y;
00444   k -= base::m_dataWindow.min.z;
00445   // Access data
00446   return m_data[i + j * m_memSize.x + k * m_memSizeXY];
00447 }
00448 
00449 //----------------------------------------------------------------------------//
00450 
00451 template <class Data_T>
00452 Data_T& DenseField<Data_T>::fastLValue(int i, int j, int k)
00453 {
00454   assert (i >= base::m_dataWindow.min.x);
00455   assert (i <= base::m_dataWindow.max.x);
00456   assert (j >= base::m_dataWindow.min.y);
00457   assert (j <= base::m_dataWindow.max.y);
00458   assert (k >= base::m_dataWindow.min.z);
00459   assert (k <= base::m_dataWindow.max.z);
00460   // Add crop window offset
00461   i -= base::m_dataWindow.min.x;
00462   j -= base::m_dataWindow.min.y;
00463   k -= base::m_dataWindow.min.z;
00464   // Access data
00465   return m_data[i + j * m_memSize.x + k * m_memSizeXY];
00466 }
00467 
00468 //----------------------------------------------------------------------------//
00469 
00470 template <class Data_T>
00471 typename DenseField<Data_T>::const_iterator 
00472 DenseField<Data_T>::cbegin() const
00473 { 
00474   if (FieldRes::dataResolution() == V3i(0))
00475     return cend();
00476   return const_iterator(*this, base::m_dataWindow, base::m_dataWindow.min); 
00477 }
00478 
00479 //----------------------------------------------------------------------------//
00480 
00481 template <class Data_T>
00482 typename DenseField<Data_T>::const_iterator 
00483 DenseField<Data_T>::cbegin(const Box3i &subset) const
00484 { 
00485   if (subset.isEmpty())
00486     return cend(subset);
00487   return const_iterator(*this, subset, subset.min); 
00488 }
00489 
00490 //----------------------------------------------------------------------------//
00491 
00492 template <class Data_T>
00493 typename DenseField<Data_T>::const_iterator 
00494 DenseField<Data_T>::cend() const
00495 { 
00496   return const_iterator(*this, base::m_dataWindow, 
00497                         V3i(base::m_dataWindow.min.x, 
00498                             base::m_dataWindow.min.y,
00499                             base::m_dataWindow.max.z + 1));
00500 }
00501 
00502 //----------------------------------------------------------------------------//
00503 
00504 template <class Data_T>
00505 typename DenseField<Data_T>::const_iterator 
00506 DenseField<Data_T>::cend(const Box3i &subset) const
00507 { 
00508   return const_iterator(*this, subset, 
00509                         V3i(subset.min.x, subset.min.y, subset.max.z + 1));
00510 }
00511 
00512 //----------------------------------------------------------------------------//
00513 
00514 template <class Data_T>
00515 typename DenseField<Data_T>::iterator 
00516 DenseField<Data_T>::begin()
00517 { 
00518   if (FieldRes::dataResolution() == V3i(0))
00519     return end();
00520   return iterator(*this, base::m_dataWindow, base::m_dataWindow.min); }
00521 
00522 //----------------------------------------------------------------------------//
00523 
00524 template <class Data_T>
00525 typename DenseField<Data_T>::iterator 
00526 DenseField<Data_T>::begin(const Box3i &subset)
00527 { 
00528   if (subset.isEmpty())
00529     return end(subset);
00530   return iterator(*this, subset, subset.min); 
00531 }
00532 
00533 //----------------------------------------------------------------------------//
00534 
00535 template <class Data_T>
00536 typename DenseField<Data_T>::iterator 
00537 DenseField<Data_T>::end()
00538 { 
00539   return iterator(*this, base::m_dataWindow, 
00540                   V3i(base::m_dataWindow.min.x, 
00541                       base::m_dataWindow.min.y,
00542                       base::m_dataWindow.max.z + 1));
00543 }
00544 
00545 //----------------------------------------------------------------------------//
00546 
00547 template <class Data_T>
00548 typename DenseField<Data_T>::iterator 
00549 DenseField<Data_T>::end(const Box3i &subset)
00550 { 
00551   return iterator(*this, subset, 
00552                   V3i(subset.min.x, subset.min.y, subset.max.z + 1));
00553 }
00554 
00555 //----------------------------------------------------------------------------//
00556 
00557 template <class Data_T>
00558 void DenseField<Data_T>::sizeChanged() 
00559 {
00560   // Call base class
00561   base::sizeChanged();
00562 
00563   // Calculate offsets
00564   m_memSize = base::m_dataWindow.max - base::m_dataWindow.min + V3i(1);
00565   m_memSizeXY = m_memSize.x * m_memSize.y;
00566 
00567   // Check that mem size is >= 0 in all dimensions
00568   if (base::m_dataWindow.max.x < base::m_dataWindow.min.x ||
00569       base::m_dataWindow.max.y < base::m_dataWindow.min.y ||
00570       base::m_dataWindow.max.z < base::m_dataWindow.min.z)
00571     throw Exc::ResizeException("Attempt to resize ResizableField object "
00572                                "using negative size. Data window was: " +
00573                                boost::lexical_cast<std::string>(
00574                                  base::m_dataWindow.min) + " - " +
00575                                boost::lexical_cast<std::string>(
00576                                  base::m_dataWindow.max));
00577 
00578   // Allocate memory
00579   try {
00580     std::vector<Data_T>().swap(m_data);
00581     m_data.resize(m_memSize.x * m_memSize.y * m_memSize.z);
00582   }
00583   catch (std::bad_alloc &e) {
00584     throw Exc::MemoryException("Couldn't allocate DenseField of size " + 
00585                                boost::lexical_cast<std::string>(m_memSize));
00586   }
00587 }
00588 
00589 //----------------------------------------------------------------------------//
00590 
00591 template <class Data_T>
00592 inline Data_T* DenseField<Data_T>::ptr(int i, int j, int k)
00593 {
00594   // Add crop window offset
00595   i -= base::m_dataWindow.min.x;
00596   j -= base::m_dataWindow.min.y;
00597   k -= base::m_dataWindow.min.z;
00598   // Access data
00599   return &m_data[i + j * m_memSize.x + k * m_memSizeXY];      
00600 }
00601 
00602 //----------------------------------------------------------------------------//
00603 
00604 template <class Data_T>
00605 inline const Data_T* DenseField<Data_T>::ptr(int i, int j, int k) const
00606 {
00607   // Add crop window offset
00608   i -= base::m_dataWindow.min.x;
00609   j -= base::m_dataWindow.min.y;
00610   k -= base::m_dataWindow.min.z;
00611   // Access data
00612   return &m_data[i + j * m_memSize.x + k * m_memSizeXY];
00613 }
00614 
00615 //----------------------------------------------------------------------------//
00616 
00617 FIELD3D_NAMESPACE_HEADER_CLOSE
00618 
00619 //----------------------------------------------------------------------------//
00620 
00621 #endif // Include guard