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