mdsTriIterator.h

Go to the documentation of this file.
00001 //==============================================================================
00015 #ifndef MDS_TRIITERATOR_H
00016 #define MDS_TRIITERATOR_H
00017 
00018 #include "mdsTriBase.h"
00019 
00020 // MDSTk
00021 #include <MDSTk/Base/mdsMemory.h>
00022 #include <MDSTk/Base/mdsIterator.h>
00023 #include <MDSTk/Math/mdsBase.h>
00024 
00025 // VCTL
00026 #include <VectorEntity/mcentity.h>
00027 
00028 
00029 namespace mds
00030 {
00031 
00032 // Declare iterator traits first...
00033 MDS_ITERATOR_TRAITS(seg, CTriIterator, seg::CTriBase::tPixel);
00034 
00035 namespace seg
00036 {
00037 
00038 //==============================================================================
00043 class CTriIterator
00044     : public mds::base::CIteratorBase<CTriIterator>
00045     , public mds::base::CContainerHolder<CTriBase::tImage, CTriBase::tPixel>
00046 {
00047 public:
00049     typedef mds::base::CContainerHolder<CTriBase::tImage, CTriBase::tPixel> base;
00050 
00052     typedef CTriBase::tImage tImage;
00053     typedef CTriBase::tPixel tPixel;
00054 
00055 public:
00057     CTriIterator(tImage *pImage, vctl::MCTri *pTriangle)
00058     {
00059         init(pImage, pTriangle);
00060     }
00061 
00063     CTriIterator(const CTriIterator& It)
00064         : base(It)
00065     {
00066         mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00067     }
00068 
00070     ~CTriIterator() {}
00071 
00073     CTriIterator& operator=(const CTriIterator& It)
00074     {
00075         base::m_pContainer = It.m_pContainer;
00076         base::m_pItem = It.m_pItem;
00077         mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00078         return *this;
00079     }
00080 
00081 
00083     mds::tSize getX() const { return m_Impl.m_X; }
00084     mds::tSize getY() const { return m_Impl.m_Y; }
00085 
00088     bool isEnd() const { return (m_Impl.m_Y > m_Impl.m_iMaxY); }
00089 
00090 protected:
00092     struct SDataMembers
00093     {
00095         int m_iMinX, m_iMaxX, m_iMinY, m_iMaxY;
00096 
00098         int m_iFDX1, m_iFDX2, m_iFDX3;
00099         int m_iFDY1, m_iFDY2, m_iFDY3;
00100 
00102         int m_iCY1, m_iCY2, m_iCY3;
00103         int m_iCX1, m_iCX2, m_iCX3;
00104 
00106         mds::tSize m_X, m_Y;
00107     };
00108 
00110     SDataMembers m_Impl;
00111 
00112 public:
00114     void advance()
00115     {
00116         do {
00117             if( isEnd() )
00118             {
00119                 break;
00120             }
00121             else
00122             {
00123                 next();
00124             }
00125         } while( !isInner() );
00126     }
00127 
00128 protected:
00130     bool isInner()
00131     {
00132         return (m_Impl.m_iCX1 <= 0 && m_Impl.m_iCX2 <= 0 && m_Impl.m_iCX3 <= 0);
00133     }
00134 
00136     void init(tImage *pImage, vctl::MCTri *pTriangle)
00137     {
00138         MDS_ASSERT(pTriangle);
00139 
00140         // Get vertices of the triangle
00141         vctl::MCVertex *pVertices[3];
00142         pTriangle->GetVerticeS(pVertices);
00143 
00144         // Fixed-point coordinates
00145         int iY1 = mds::math::round2Int(16.0 * pVertices[0]->GetY());
00146         int iY2 = mds::math::round2Int(16.0 * pVertices[1]->GetY());
00147         int iY3 = mds::math::round2Int(16.0 * pVertices[2]->GetY());
00148 
00149         int iX1 = mds::math::round2Int(16.0 * pVertices[0]->GetX());
00150         int iX2 = mds::math::round2Int(16.0 * pVertices[1]->GetX());
00151         int iX3 = mds::math::round2Int(16.0 * pVertices[2]->GetX());
00152 
00153         // Deltas
00154         int iDX1 = iX2 - iX1;
00155         int iDX2 = iX3 - iX2;
00156         int iDX3 = iX1 - iX3;
00157 
00158         int iDY1 = iY2 - iY1;
00159         int iDY2 = iY3 - iY2;
00160         int iDY3 = iY1 - iY3;
00161 
00162         // Fixed-point deltas
00163         m_Impl.m_iFDX1 = iDX1 << 4;
00164         m_Impl.m_iFDX2 = iDX2 << 4;
00165         m_Impl.m_iFDX3 = iDX3 << 4;
00166 
00167         m_Impl.m_iFDY1 = iDY1 << 4;
00168         m_Impl.m_iFDY2 = iDY2 << 4;
00169         m_Impl.m_iFDY3 = iDY3 << 4;
00170 
00171         // Bounding rectangle
00172         m_Impl.m_iMinX = mds::math::getMin(iX1, iX2, iX3) >> 4;
00173         m_Impl.m_iMaxX = mds::math::getMax(iX1, iX2, iX3) >> 4;
00174         m_Impl.m_iMinY = mds::math::getMin(iY1, iY2, iY3) >> 4;
00175         m_Impl.m_iMaxY = mds::math::getMax(iY1, iY2, iY3) >> 4;
00176 
00177         // Half-edge constants
00178         int iC1 = iDX1 * iY1 - iDY1 * iX1;
00179         int iC2 = iDX2 * iY2 - iDY2 * iX2;
00180         int iC3 = iDX3 * iY3 - iDY3 * iX3;
00181 
00182         // Initialization
00183         m_Impl.m_iCY1 = iC1 - iDX1 * (m_Impl.m_iMinY << 4) + iDY1 * (m_Impl.m_iMinX << 4);
00184         m_Impl.m_iCY2 = iC2 - iDX2 * (m_Impl.m_iMinY << 4) + iDY2 * (m_Impl.m_iMinX << 4);
00185         m_Impl.m_iCY3 = iC3 - iDX3 * (m_Impl.m_iMinY << 4) + iDY3 * (m_Impl.m_iMinX << 4);
00186 
00187         m_Impl.m_iCX1 = m_Impl.m_iCY1;
00188         m_Impl.m_iCX2 = m_Impl.m_iCY2;
00189         m_Impl.m_iCX3 = m_Impl.m_iCY3;
00190 
00191         m_Impl.m_X = m_Impl.m_iMinX;
00192         m_Impl.m_Y = m_Impl.m_iMinY;
00193 
00194         m_pContainer = pImage;
00195         m_pItem = pImage->getPtr(m_Impl.m_X, m_Impl.m_Y);
00196 
00197         // Find the first pixel
00198         if( !isInner() )
00199         {
00200             advance();
00201         }
00202     }
00203 
00205     void next()
00206     {
00207         ++m_pItem;
00208         if( ++m_Impl.m_X > m_Impl.m_iMaxX )
00209         {
00210             m_Impl.m_X = m_Impl.m_iMinX;
00211             ++m_Impl.m_Y;
00212             m_Impl.m_iCY1 -= m_Impl.m_iFDX1;
00213             m_Impl.m_iCY2 -= m_Impl.m_iFDX2;
00214             m_Impl.m_iCY3 -= m_Impl.m_iFDX3;
00215             m_Impl.m_iCX1 = m_Impl.m_iCY1;
00216             m_Impl.m_iCX2 = m_Impl.m_iCY2;
00217             m_Impl.m_iCX3 = m_Impl.m_iCY3;
00218             m_pItem = m_pContainer->getPtr(m_Impl.m_X, m_Impl.m_Y);
00219         }
00220         else
00221         {
00222             m_Impl.m_iCX1 += m_Impl.m_iFDY1;
00223             m_Impl.m_iCX2 += m_Impl.m_iFDY2;
00224             m_Impl.m_iCX3 += m_Impl.m_iFDY3;
00225         }
00226     }
00227 };
00228 
00229 
00230 } // namespace seg
00231 } // namespace mds
00232 
00233 #endif // MDS_TRIITERATOR_H
00234 

Generated on Thu Mar 11 10:35:45 2010 for MDSTk Extension Libraries by  doxygen 1.4.6-NO