00001
00015 #ifndef MDS_TRIITERATOR_H
00016 #define MDS_TRIITERATOR_H
00017
00018 #include "mdsTriBase.h"
00019
00020
00021 #include <MDSTk/Base/mdsMemory.h>
00022 #include <MDSTk/Base/mdsIterator.h>
00023 #include <MDSTk/Math/mdsBase.h>
00024
00025
00026 #include <VectorEntity/mcentity.h>
00027
00028
00029 namespace mds
00030 {
00031
00032
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
00141 vctl::MCVertex *pVertices[3];
00142 pTriangle->GetVerticeS(pVertices);
00143
00144
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
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
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
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
00178 int iC1 = iDX1 * iY1 - iDY1 * iX1;
00179 int iC2 = iDX2 * iY2 - iDY2 * iX2;
00180 int iC3 = iDX3 * iY3 - iDY3 * iX3;
00181
00182
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
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 }
00231 }
00232
00233 #endif // MDS_TRIITERATOR_H
00234