Field3D
MACField.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_MACField_H_
00045 #define _INCLUDED_Field3D_MACField_H_
00046 
00047 #include <vector>
00048 #include <boost/lexical_cast.hpp>
00049 
00050 #include "Field.h"
00051 
00052 //----------------------------------------------------------------------------//
00053 
00054 #include "ns.h"
00055 
00056 FIELD3D_NAMESPACE_OPEN
00057 
00058 //----------------------------------------------------------------------------//
00059 // Forward declarations 
00060 //----------------------------------------------------------------------------//
00061 
00062 template <class T>
00063 class LinearMACFieldInterp; 
00064 template <class T>
00065 class CubicMACFieldInterp; 
00066 
00067 //----------------------------------------------------------------------------//
00068 // Enumerators 
00069 //----------------------------------------------------------------------------//
00070 
00071 enum MACComponent {
00072   MACCompU = 0,
00073   MACCompV,
00074   MACCompW
00075 };
00076 
00077 //----------------------------------------------------------------------------//
00078 // MACField
00079 //----------------------------------------------------------------------------//
00080 
00092 //----------------------------------------------------------------------------//
00093 
00094 template <class Data_T>
00095 class MACField : public ResizableField<Data_T>
00096 {
00097 public:
00098 
00099   // Typedefs ------------------------------------------------------------------
00100   
00101   typedef boost::intrusive_ptr<MACField> Ptr;
00102   typedef std::vector<Ptr> Vec;
00103 
00105   typedef typename Data_T::BaseType real_t;
00106 
00107   typedef LinearMACFieldInterp<Data_T> LinearInterp;
00108   typedef CubicMACFieldInterp<Data_T> CubicInterp;
00109 
00110   // Constructors --------------------------------------------------------------
00111 
00114 
00116   MACField();
00117 
00118   // \}
00119 
00120   // Main methods --------------------------------------------------------------
00121 
00123   virtual void clear(const Data_T &value);
00124 
00125   // From Field base class -----------------------------------------------------
00126 
00129 
00131   virtual Data_T value(int i, int j, int k) const;
00132   virtual long long int memSize() const;
00133 
00135 
00136   // RTTI replacement ----------------------------------------------------------
00137 
00138   typedef MACField<Data_T> class_type;
00139   DEFINE_FIELD_RTTI_CONCRETE_CLASS;
00140 
00141   // From WritableField base class ---------------------------------------------
00142 
00145 
00149   virtual Data_T& lvalue(int i, int j, int k);
00150 
00152   
00153   // Concrete component access -------------------------------------------------
00154 
00157 
00160   const real_t& u(int i, int j, int k) const;
00163   real_t& u(int i, int j, int k);
00166   const real_t& v(int i, int j, int k) const;
00169   real_t& v(int i, int j, int k);
00172   const real_t& w(int i, int j, int k) const;
00175   real_t& w(int i, int j, int k);
00176 
00178 
00179   // Iterators -----------------------------------------------------------------
00180 
00188 
00189 
00190 
00192   class const_mac_comp_iterator;
00194   class mac_comp_iterator;
00195 
00197   const_mac_comp_iterator cbegin_comp(MACComponent comp) const;
00199   const_mac_comp_iterator cbegin_comp(MACComponent comp, 
00200                                       const Box3i &subset) const;
00202   const_mac_comp_iterator cend_comp(MACComponent comp) const;
00204   const_mac_comp_iterator cend_comp(MACComponent comp, 
00205                                     const Box3i &subset) const;
00206   
00208   mac_comp_iterator begin_comp(MACComponent comp);
00210   mac_comp_iterator begin_comp(MACComponent comp, 
00211                                const Box3i &subset);
00213   mac_comp_iterator end_comp(MACComponent comp);
00215   mac_comp_iterator end_comp(MACComponent comp, 
00216                              const Box3i &subset);
00217 
00219 
00220   // Utility methods -----------------------------------------------------------
00221 
00223   real_t uCenter(int i, int j, int k) const
00224   {
00225     return (u(i, j, k) + u(i + 1, j, k)) * 0.5;
00226   }
00228   real_t vCenter(int i, int j, int k) const
00229   {
00230     return (v(i, j, k) + v(i, j + 1, k)) * 0.5;
00231   }
00233   real_t wCenter(int i, int j, int k) const
00234   {
00235     return (w(i, j, k) + w(i, j, k + 1)) * 0.5;
00236   }
00237 
00240   void copyMAC(MACField::Ptr other)
00241   {
00242     matchDefinition(other);
00243     std::copy(other->m_u.begin(), other->m_u.end(), m_u.begin());
00244     std::copy(other->m_v.begin(), other->m_v.end(), m_v.begin());
00245     std::copy(other->m_w.begin(), other->m_w.end(), m_w.begin());
00246   }
00247 
00248   // Utility methods -----------------------------------------------------------
00249 
00251   V3i getComponentSize() const
00252   { return V3i(m_u.size(), m_v.size(), m_w.size()); }
00253   
00254   // From FieldBase ------------------------------------------------------------
00255 
00258   virtual std::string className() const
00259   { return std::string("MACField"); }
00260 
00261   virtual FieldBase::Ptr clone() const
00262   { return Ptr(new MACField(*this)); }
00263 
00265 
00266  protected:
00267 
00268   // From ResizableField class ---------------------------------------------
00269 
00270   virtual void sizeChanged();
00271 
00272   // Concrete component access -------------------------------------------------
00273 
00276   const real_t* uPtr(int i, int j, int k) const;
00279   real_t* uPtr(int i, int j, int k);
00282   const real_t* vPtr(int i, int j, int k) const;
00285   real_t* vPtr(int i, int j, int k);
00288   const real_t* wPtr(int i, int j, int k) const;
00291   real_t* wPtr(int i, int j, int k);
00292 
00293   // Data members --------------------------------------------------------------
00294 
00296   std::vector<real_t> m_u;
00298   std::vector<real_t> m_v;
00300   std::vector<real_t> m_w;
00301 
00303   V3i m_uSize;
00305   int m_uSizeXY;
00307   V3i m_vSize;
00309   int m_vSizeXY;
00311   V3i m_wSize;
00313   int m_wSizeXY;
00314 
00316   mutable Data_T m_dummy;
00317 
00318  private:
00319 
00320   // Typedefs ------------------------------------------------------------------
00321 
00322   typedef ResizableField<Data_T> base;
00323 
00324 };
00325 
00326 //----------------------------------------------------------------------------//
00327 // Typedefs
00328 //----------------------------------------------------------------------------//
00329 
00330 typedef MACField<V3h> MACField3h;
00331 typedef MACField<V3f> MACField3f;
00332 typedef MACField<V3d> MACField3d;
00333 
00334 //----------------------------------------------------------------------------//
00335 // MACField::const_mac_comp_iterator
00336 //----------------------------------------------------------------------------//
00337 
00338 template <class Data_T>
00339 class MACField<Data_T>::const_mac_comp_iterator
00340 {
00341 public:
00342 
00343   // Typedefs ------------------------------------------------------------------
00344 
00345   typedef MACField<Data_T> class_type;
00346   typedef typename MACField<Data_T>::real_t real_t;
00347 
00348   // Constructors --------------------------------------------------------------
00349 
00350   const_mac_comp_iterator(MACComponent comp, 
00351                           const class_type &field, 
00352                           const Box3i &window, 
00353                           const V3i &currentPos)
00354     : x(currentPos.x), y(currentPos.y), z(currentPos.z), 
00355       m_p(NULL), m_window(window), m_comp(comp), 
00356       m_field(field)
00357   { 
00358     updatePointer();
00359   }
00360 
00361   // Operators -----------------------------------------------------------------
00362 
00363   const const_mac_comp_iterator& operator ++ ()
00364   {
00365     if (x == m_window.max.x) {
00366       if (y == m_window.max.y) {
00367         x = m_window.min.x; 
00368         y = m_window.min.y; 
00369         ++z;
00370       } else {
00371         x = m_window.min.x; 
00372         ++y;
00373       }
00374       updatePointer();
00375     } else {
00376       ++x;
00377       ++m_p;
00378     }
00379     return *this;
00380   }
00381 
00382   template <class Iter_T>
00383   inline bool operator == (const Iter_T &rhs) const
00384   {
00385     return m_p == &(*rhs);
00386   }
00387 
00388   template <class Iter_T>
00389   inline bool operator != (const Iter_T &rhs) const
00390   {
00391     return m_p != &(*rhs);
00392   }
00393 
00394   inline const real_t& operator * () const
00395   {
00396     return *m_p;
00397   }
00398 
00399   inline const real_t* operator -> () const
00400   {
00401     return m_p;
00402   }
00403 
00404   // Public data members -------------------------------------------------------
00405 
00407   int x, y, z;
00408 
00409 private:
00410 
00411   // Convenience methods -------------------------------------------------------
00412 
00413   void updatePointer()
00414   {
00415     switch (m_comp) {
00416     case MACCompU:
00417       m_p = m_field.uPtr(x, y, z);
00418       break;
00419     case MACCompV:
00420       m_p = m_field.vPtr(x, y, z);
00421       break;
00422     case MACCompW:
00423       m_p = m_field.wPtr(x, y, z);
00424       break;
00425     default:
00426       assert(false && "Illegal MACComponent in const_mac_comp_iterator");
00427     }    
00428   }
00429 
00430   // Private data members ------------------------------------------------------
00431 
00433   const real_t *m_p;
00435   Box3i m_window;
00437   MACComponent m_comp;
00439   const class_type &m_field;
00440 
00441 };
00442 
00443 //----------------------------------------------------------------------------//
00444 
00445 template <class Data_T>
00446 class MACField<Data_T>::mac_comp_iterator
00447 {
00448 public:
00449 
00450   // Typedefs ------------------------------------------------------------------
00451 
00452   typedef MACField<Data_T> class_type;
00453   typedef typename MACField<Data_T>::real_t real_t;
00454 
00455   // Constructors --------------------------------------------------------------
00456 
00457   mac_comp_iterator(MACComponent comp, class_type &field, 
00458                     const Box3i &window, const V3i &currentPos)
00459     : x(currentPos.x), y(currentPos.y), z(currentPos.z), 
00460       m_p(NULL), m_window(window), m_comp(comp), 
00461       m_field(field)
00462   { 
00463     updatePointer();
00464   }
00465 
00466   // Operators -----------------------------------------------------------------
00467 
00468   mac_comp_iterator& operator ++ ()
00469   {
00470     if (x == m_window.max.x) {
00471       if (y == m_window.max.y) {
00472         x = m_window.min.x; 
00473         y = m_window.min.y; 
00474         ++z;
00475       } else {
00476         x = m_window.min.x; 
00477         ++y;
00478       }
00479       updatePointer();
00480     } else {
00481       ++x;
00482       ++m_p;
00483     }
00484     return *this;
00485   }
00486 
00487   template <class Iter_T>
00488   inline bool operator == (const Iter_T &rhs) const
00489   {
00490     return m_p == &(*rhs);
00491   }
00492 
00493   template <class Iter_T>
00494   inline bool operator != (const Iter_T &rhs) const
00495   {
00496     return m_p != &(*rhs);
00497   }
00498 
00499   inline real_t& operator * () const
00500   {
00501     return *m_p;
00502   }
00503 
00504   inline real_t* operator -> () const
00505   {
00506     return m_p;
00507   }
00508 
00509   // Public data members -------------------------------------------------------
00510 
00512   int x, y, z;
00513 
00514 private:
00515 
00516   // Convenience methods -------------------------------------------------------
00517 
00518   void updatePointer()
00519   {
00520     switch (m_comp) {
00521     case MACCompU:
00522       m_p = m_field.uPtr(x, y, z);
00523       break;
00524     case MACCompV:
00525       m_p = m_field.vPtr(x, y, z);
00526       break;
00527     case MACCompW:
00528       m_p = m_field.wPtr(x, y, z);
00529       break;
00530     default:
00531       assert(false && "Illegal MACComponent in const_mac_comp_iterator");
00532     }    
00533   }
00534 
00535   // Private data members ------------------------------------------------------
00536 
00538   real_t *m_p;
00540   Box3i m_window;
00542   MACComponent m_comp;
00544   class_type &m_field;
00545 
00546 };
00547 
00548 //----------------------------------------------------------------------------//
00549 // Implementation specific helpers 
00550 //----------------------------------------------------------------------------//
00551 
00552 namespace MACFieldUtil {
00553 
00554   inline Box3i makeDataWindowForComponent(Box3i dataWindow, MACComponent comp)
00555   {
00556     switch (comp) {
00557     case MACCompU:
00558       dataWindow.max += V3i(1, 0, 0);
00559       break;
00560     case MACCompV:
00561       dataWindow.max += V3i(0, 1, 0);
00562       break;
00563     case MACCompW:
00564       dataWindow.max += V3i(0, 0, 1);
00565       break;
00566     default:
00567       assert(false && "Illegal MACComponent in makeDataWindowForComponent");
00568     } 
00569     return dataWindow;
00570   }
00571 
00572 }
00573 
00574 //----------------------------------------------------------------------------//
00575 // MACField implementations
00576 //----------------------------------------------------------------------------//
00577 
00578 template <class Data_T>
00579 MACField<Data_T>::MACField()
00580   : base()
00581 {
00582   
00583 }
00584 
00585 //----------------------------------------------------------------------------//
00586 
00587 template <class Data_T>
00588 void MACField<Data_T>::clear(const Data_T &value)
00589 {
00590   std::fill(m_u.begin(), m_u.end(), value.x);
00591   std::fill(m_v.begin(), m_v.end(), value.y);
00592   std::fill(m_w.begin(), m_w.end(), value.z);
00593 }
00594 
00595 //----------------------------------------------------------------------------//
00596 
00597 template <class Data_T>
00598 Data_T MACField<Data_T>::value(int i, int j, int k) const
00599 {
00600   return Data_T(uCenter(i, j, k), vCenter(i, j, k), wCenter(i, j, k));
00601 }
00602 
00603 //----------------------------------------------------------------------------//
00604 
00605 template <class Data_T>
00606 long long int MACField<Data_T>::memSize() const
00607 { 
00608   long long int superClassMemSize = base::memSize();
00609   long long int vectorMemSize = 
00610     (m_u.capacity() + m_v.capacity() + m_w.capacity()) * sizeof(real_t);
00611   return sizeof(*this) + vectorMemSize + superClassMemSize; 
00612 }
00613 
00614 //----------------------------------------------------------------------------//
00615 
00616 template <class Data_T>
00617 Data_T& MACField<Data_T>::lvalue(int i, int j, int k)
00618 {
00619   m_dummy = value(i, j, k);
00620   return m_dummy;
00621 }
00622 
00623 //----------------------------------------------------------------------------//
00624 
00625 template <class Data_T>
00626 void MACField<Data_T>::sizeChanged() 
00627 {
00628   // Call base class
00629   base::sizeChanged();
00630 
00631   V3i baseSize = 
00632     base::m_dataWindow.max - base::m_dataWindow.min + V3i(1);
00633 
00634   if (std::min(std::min(baseSize.x, baseSize.y), baseSize.z) < 0)
00635     throw Exc::ResizeException("Attempt to resize ResizableField object "
00636                                "using negative size. Data window was: " +
00637                                boost::lexical_cast<std::string>(baseSize));
00638 
00639   // Calculate the size for each component of the MAC field
00640   m_uSize = baseSize + V3i(1, 0, 0);
00641   m_vSize = baseSize + V3i(0, 1, 0);
00642   m_wSize = baseSize + V3i(0, 0, 1);
00643 
00644   // Calculate the size of each z slice
00645   m_uSizeXY = m_uSize.x * m_uSize.y;
00646   m_vSizeXY = m_vSize.x * m_vSize.y;
00647   m_wSizeXY = m_wSize.x * m_wSize.y;
00648 
00649   // Allocate memory
00650   try {
00651     m_u.resize(m_uSize.x * m_uSize.y * m_uSize.z);
00652     m_v.resize(m_vSize.x * m_vSize.y * m_vSize.z);
00653     m_w.resize(m_wSize.x * m_wSize.y * m_wSize.z);
00654   }
00655   catch (std::bad_alloc &e) {
00656     throw Exc::MemoryException("Couldn't allocate MACField of size " + 
00657                                boost::lexical_cast<std::string>(baseSize));
00658   }
00659 
00660 }
00661 
00662 //----------------------------------------------------------------------------//
00663 
00664 template <class Data_T>
00665 const typename MACField<Data_T>::real_t& 
00666 MACField<Data_T>::u(int i, int j, int k) const
00667 {
00668   assert (i >= base::m_dataWindow.min.x);
00669   assert (i <= base::m_dataWindow.max.x + 1);
00670   assert (j >= base::m_dataWindow.min.y);
00671   assert (j <= base::m_dataWindow.max.y);
00672   assert (k >= base::m_dataWindow.min.z);
00673   assert (k <= base::m_dataWindow.max.z);
00674   // Add crop window offset
00675   i -= base::m_dataWindow.min.x;
00676   j -= base::m_dataWindow.min.y;
00677   k -= base::m_dataWindow.min.z;
00678   return m_u[i + j * m_uSize.x + k * m_uSizeXY];
00679 }
00680 
00681 //----------------------------------------------------------------------------//
00682 
00683 template <class Data_T>
00684 typename MACField<Data_T>::real_t& 
00685 MACField<Data_T>::u(int i, int j, int k)
00686 {
00687   assert (i >= base::m_dataWindow.min.x);
00688   assert (i <= base::m_dataWindow.max.x + 1);
00689   assert (j >= base::m_dataWindow.min.y);
00690   assert (j <= base::m_dataWindow.max.y);
00691   assert (k >= base::m_dataWindow.min.z);
00692   assert (k <= base::m_dataWindow.max.z);
00693   // Add crop window offset
00694   i -= base::m_dataWindow.min.x;
00695   j -= base::m_dataWindow.min.y;
00696   k -= base::m_dataWindow.min.z;
00697   return m_u[i + j * m_uSize.x + k * m_uSizeXY];
00698 }
00699 
00700 //----------------------------------------------------------------------------//
00701 
00702 template <class Data_T>
00703 const typename MACField<Data_T>::real_t& 
00704 MACField<Data_T>::v(int i, int j, int k) const
00705 {
00706   assert (i >= base::m_dataWindow.min.x);
00707   assert (i <= base::m_dataWindow.max.x);
00708   assert (j >= base::m_dataWindow.min.y);
00709   assert (j <= base::m_dataWindow.max.y + 1);
00710   assert (k >= base::m_dataWindow.min.z);
00711   assert (k <= base::m_dataWindow.max.z);
00712   // Add crop window offset
00713   i -= base::m_dataWindow.min.x;
00714   j -= base::m_dataWindow.min.y;
00715   k -= base::m_dataWindow.min.z;
00716   return m_v[i + j * m_vSize.x + k * m_vSizeXY];
00717 }
00718 
00719 //----------------------------------------------------------------------------//
00720 
00721 template <class Data_T>
00722 typename MACField<Data_T>::real_t& 
00723 MACField<Data_T>::v(int i, int j, int k)
00724 {
00725   assert (i >= base::m_dataWindow.min.x);
00726   assert (i <= base::m_dataWindow.max.x);
00727   assert (j >= base::m_dataWindow.min.y);
00728   assert (j <= base::m_dataWindow.max.y + 1);
00729   assert (k >= base::m_dataWindow.min.z);
00730   assert (k <= base::m_dataWindow.max.z);
00731   // Add crop window offset
00732   i -= base::m_dataWindow.min.x;
00733   j -= base::m_dataWindow.min.y;
00734   k -= base::m_dataWindow.min.z;
00735   return m_v[i + j * m_vSize.x + k * m_vSizeXY];
00736 }
00737 
00738 //----------------------------------------------------------------------------//
00739 
00740 template <class Data_T>
00741 const typename MACField<Data_T>::real_t& 
00742 MACField<Data_T>::w(int i, int j, int k) const
00743 {
00744   assert (i >= base::m_dataWindow.min.x);
00745   assert (i <= base::m_dataWindow.max.x);
00746   assert (j >= base::m_dataWindow.min.y);
00747   assert (j <= base::m_dataWindow.max.y);
00748   assert (k >= base::m_dataWindow.min.z);
00749   assert (k <= base::m_dataWindow.max.z + 1);
00750   // Add crop window offset
00751   i -= base::m_dataWindow.min.x;
00752   j -= base::m_dataWindow.min.y;
00753   k -= base::m_dataWindow.min.z;
00754   return m_w[i + j * m_wSize.x + k * m_wSizeXY];
00755 }
00756 
00757 //----------------------------------------------------------------------------//
00758 
00759 template <class Data_T>
00760 typename MACField<Data_T>::real_t& 
00761 MACField<Data_T>::w(int i, int j, int k)
00762 {
00763   assert (i >= base::m_dataWindow.min.x);
00764   assert (i <= base::m_dataWindow.max.x);
00765   assert (j >= base::m_dataWindow.min.y);
00766   assert (j <= base::m_dataWindow.max.y);
00767   assert (k >= base::m_dataWindow.min.z);
00768   assert (k <= base::m_dataWindow.max.z + 1);
00769   // Add crop window offset
00770   i -= base::m_dataWindow.min.x;
00771   j -= base::m_dataWindow.min.y;
00772   k -= base::m_dataWindow.min.z;
00773   return m_w[i + j * m_wSize.x + k * m_wSizeXY];
00774 }
00775 
00776 //----------------------------------------------------------------------------//
00777 
00778 template <class Data_T>
00779 typename MACField<Data_T>::const_mac_comp_iterator 
00780 MACField<Data_T>::cbegin_comp(MACComponent comp) const
00781 {
00782   using namespace MACFieldUtil;
00783   if (FieldRes::dataResolution() == V3i(0))
00784     return cend_comp(comp);
00785   Box3i dataWindow = 
00786     makeDataWindowForComponent(base::m_dataWindow, comp);
00787   return const_mac_comp_iterator(comp, *this, dataWindow, dataWindow.min);
00788 }
00789 
00790 //----------------------------------------------------------------------------//
00791 
00792 template <class Data_T>
00793 typename MACField<Data_T>::const_mac_comp_iterator 
00794 MACField<Data_T>::cbegin_comp(MACComponent comp, const Box3i &subset) const
00795 {
00796   using namespace MACFieldUtil;
00797   if (subset.isEmpty())
00798     return cend_comp(comp, subset);
00799   Box3i dataWindow = makeDataWindowForComponent(subset, comp);
00800   return const_mac_comp_iterator(comp, *this, dataWindow, subset.min);
00801 }
00802 
00803 //----------------------------------------------------------------------------//
00804 
00805 template <class Data_T>
00806 typename MACField<Data_T>::const_mac_comp_iterator 
00807 MACField<Data_T>::cend_comp(MACComponent comp) const
00808 {
00809   using namespace MACFieldUtil;
00810   Box3i dataWindow = 
00811     makeDataWindowForComponent(base::m_dataWindow, comp);
00812   return const_mac_comp_iterator(comp, *this, dataWindow, 
00813                                  V3i(dataWindow.min.x,
00814                                      dataWindow.min.y,
00815                                      dataWindow.max.z + 1));
00816 }
00817 
00818 //----------------------------------------------------------------------------//
00819 
00820 template <class Data_T>
00821 typename MACField<Data_T>::const_mac_comp_iterator 
00822 MACField<Data_T>::cend_comp(MACComponent comp, const Box3i &subset) const
00823 {
00824   using namespace MACFieldUtil;
00825   Box3i dataWindow = makeDataWindowForComponent(subset, comp);
00826   return const_mac_comp_iterator(comp, *this, dataWindow, 
00827                                  V3i(dataWindow.min.x,
00828                                      dataWindow.min.y,
00829                                      dataWindow.max.z + 1));
00830 }
00831   
00832 //----------------------------------------------------------------------------//
00833 
00834 template <class Data_T>
00835 typename MACField<Data_T>::mac_comp_iterator 
00836 MACField<Data_T>::begin_comp(MACComponent comp)
00837 {
00838   using namespace MACFieldUtil;
00839   if (FieldRes::dataResolution() == V3i(0))
00840     return end_comp(comp);
00841   Box3i dataWindow = makeDataWindowForComponent(base::m_dataWindow, comp);
00842   return mac_comp_iterator(comp, *this, dataWindow, dataWindow.min);
00843 }
00844 
00845 //----------------------------------------------------------------------------//
00846 
00847 template <class Data_T>
00848 typename MACField<Data_T>::mac_comp_iterator 
00849 MACField<Data_T>::begin_comp(MACComponent comp, const Box3i &subset)
00850 {
00851   using namespace MACFieldUtil;
00852   if (subset.isEmpty())
00853     return end_comp(comp, subset);
00854   Box3i dataWindow = makeDataWindowForComponent(subset, comp);
00855   return mac_comp_iterator(comp, *this, dataWindow, subset.min);
00856 }
00857 
00858 //----------------------------------------------------------------------------//
00859 
00860 template <class Data_T>
00861 typename MACField<Data_T>::mac_comp_iterator 
00862 MACField<Data_T>::end_comp(MACComponent comp)
00863 {
00864   using namespace MACFieldUtil;
00865   Box3i dataWindow = makeDataWindowForComponent(base::m_dataWindow, comp);
00866   return mac_comp_iterator(comp, *this, dataWindow, V3i(dataWindow.min.x,
00867                                                         dataWindow.min.y,
00868                                                         dataWindow.max.z + 1));
00869 }
00870 
00871 //----------------------------------------------------------------------------//
00872 
00873 template <class Data_T>
00874 typename MACField<Data_T>::mac_comp_iterator 
00875 MACField<Data_T>::end_comp(MACComponent comp, const Box3i &subset)
00876 {
00877   using namespace MACFieldUtil;
00878   Box3i dataWindow = makeDataWindowForComponent(subset, comp);
00879   return mac_comp_iterator(comp, *this, dataWindow, V3i(dataWindow.min.x,
00880                                                         dataWindow.min.y,
00881                                                         dataWindow.max.z + 1));
00882 }
00883 
00884 //----------------------------------------------------------------------------//
00885 
00886 template <class Data_T>
00887 const typename MACField<Data_T>::real_t*
00888 MACField<Data_T>::uPtr(int i, int j, int k) const
00889 {
00890   // Add crop window offset
00891   i -= base::m_dataWindow.min.x;
00892   j -= base::m_dataWindow.min.y;
00893   k -= base::m_dataWindow.min.z;
00894   return &m_u[i + j * m_uSize.x + k * m_uSizeXY];
00895 }
00896 
00897 //----------------------------------------------------------------------------//
00898 
00899 template <class Data_T>
00900 typename MACField<Data_T>::real_t*
00901 MACField<Data_T>::uPtr(int i, int j, int k)
00902 {
00903   // Add crop window offset
00904   i -= base::m_dataWindow.min.x;
00905   j -= base::m_dataWindow.min.y;
00906   k -= base::m_dataWindow.min.z;
00907   return &m_u[i + j * m_uSize.x + k * m_uSizeXY];
00908 }
00909 
00910 //----------------------------------------------------------------------------//
00911 
00912 template <class Data_T>
00913 const typename MACField<Data_T>::real_t* 
00914 MACField<Data_T>::vPtr(int i, int j, int k) const
00915 {
00916   // Add crop window offset
00917   i -= base::m_dataWindow.min.x;
00918   j -= base::m_dataWindow.min.y;
00919   k -= base::m_dataWindow.min.z;
00920   return &m_v[i + j * m_vSize.x + k * m_vSizeXY];
00921 }
00922 
00923 //----------------------------------------------------------------------------//
00924 
00925 template <class Data_T>
00926 typename MACField<Data_T>::real_t* 
00927 MACField<Data_T>::vPtr(int i, int j, int k)
00928 {
00929   // Add crop window offset
00930   i -= base::m_dataWindow.min.x;
00931   j -= base::m_dataWindow.min.y;
00932   k -= base::m_dataWindow.min.z;
00933   return &m_v[i + j * m_vSize.x + k * m_vSizeXY];
00934 }
00935 
00936 //----------------------------------------------------------------------------//
00937 
00938 template <class Data_T>
00939 const typename MACField<Data_T>::real_t* 
00940 MACField<Data_T>::wPtr(int i, int j, int k) const
00941 {
00942   // Add crop window offset
00943   i -= base::m_dataWindow.min.x;
00944   j -= base::m_dataWindow.min.y;
00945   k -= base::m_dataWindow.min.z;
00946   return &m_w[i + j * m_wSize.x + k * m_wSizeXY];
00947 }
00948 
00949 //----------------------------------------------------------------------------//
00950 
00951 template <class Data_T>
00952 typename MACField<Data_T>::real_t* 
00953 MACField<Data_T>::wPtr(int i, int j, int k)
00954 {
00955   // Add crop window offset
00956   i -= base::m_dataWindow.min.x;
00957   j -= base::m_dataWindow.min.y;
00958   k -= base::m_dataWindow.min.z;
00959   return &m_w[i + j * m_wSize.x + k * m_wSizeXY];
00960 }
00961 
00962 //----------------------------------------------------------------------------//
00963 
00964 FIELD3D_NAMESPACE_HEADER_CLOSE
00965 
00966 //----------------------------------------------------------------------------//
00967 
00968 #endif // Include guard