00001
00015 #ifndef MDS_TETRATRIITERATOR_H
00016 #define MDS_TETRATRIITERATOR_H
00017
00018 #include "mdsTetraBase.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, CTetraTriIterator, seg::CTetraBase::tVoxel);
00034
00035 namespace seg
00036 {
00037
00038
00043 class CTetraTriIterator
00044 : public mds::base::CIteratorBase<CTetraTriIterator>
00045 , public mds::base::CContainerHolder<CTetraBase::tVolume, CTetraBase::tVoxel>
00046 {
00047 public:
00049 typedef mds::base::CContainerHolder<CTetraBase::tVolume, CTetraBase::tVoxel> base;
00050
00052 typedef CTetraBase::tVolume tVolume;
00053 typedef CTetraBase::tVoxel tVoxel;
00054 typedef CTetraBase::tScale tScale;
00055
00056 public:
00058 CTetraTriIterator(tVolume *pVolume, vctl::MCTri *pTriangle, tScale *pScale)
00059 : m_pScale(pScale)
00060 {
00061 MDS_ASSERT(pTriangle && pScale);
00062
00063
00064 vctl::MCVertex *pVertices[3];
00065 pTriangle->GetVerticeS(pVertices);
00066
00067 init(pVolume, pVertices[0], pVertices[1], pVertices[2]);
00068 }
00069
00071 CTetraTriIterator(tVolume *pVolume,
00072 vctl::MCPoint3D *p0,
00073 vctl::MCPoint3D *p1,
00074 vctl::MCPoint3D *p2,
00075 tScale *pScale
00076 )
00077 : m_pScale(pScale)
00078 {
00079 MDS_ASSERT(pScale);
00080
00081 init(pVolume, p0, p1, p2);
00082 }
00083
00085 CTetraTriIterator(const CTetraTriIterator& It)
00086 : base(It)
00087 , m_pScale(It.m_pScale)
00088 {
00089 mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00090 }
00091
00093 ~CTetraTriIterator() {}
00094
00096 CTetraTriIterator& operator=(const CTetraTriIterator& It)
00097 {
00098 base::m_pContainer = It.m_pContainer;
00099 base::m_pItem = It.m_pItem;
00100 mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00101 m_pScale = It.m_pScale;
00102 return *this;
00103 }
00104
00105
00107 mds::tSize getX() const { return *m_Impl.m_pX; }
00108 mds::tSize getY() const { return *m_Impl.m_pY; }
00109 mds::tSize getZ() const { return *m_Impl.m_pZ; }
00110
00112 double getRealX() const { return m_pScale->getRealX(*m_Impl.m_pX); }
00113 double getRealY() const { return m_pScale->getRealY(*m_Impl.m_pY); }
00114 double getRealZ() const { return m_pScale->getRealZ(*m_Impl.m_pZ); }
00115
00118 bool isEnd() const { return (m_Impl.m_Y > m_Impl.m_iMaxY); }
00119
00120 protected:
00122 struct SDataMembers
00123 {
00125 int m_iMinX, m_iMaxX, m_iMinY, m_iMaxY;
00126
00128 int m_iFDX1, m_iFDX2, m_iFDX3;
00129 int m_iFDY1, m_iFDY2, m_iFDY3;
00130
00132 int m_iCY1, m_iCY2, m_iCY3;
00133 int m_iCX1, m_iCX2, m_iCX3;
00134
00136 mds::tSize m_X, m_Y, m_Z;
00137
00139 mds::tSize *m_pX, *m_pY, *m_pZ;
00140
00142 double m_dDX, m_dDY;
00143
00145 double m_dY, m_dZ;
00146
00148 int m_iInv1, m_iInv2, m_iInv3;
00149 };
00150
00152 SDataMembers m_Impl;
00153
00155 tScale *m_pScale;
00156
00157 public:
00159 void advance()
00160 {
00161 do {
00162 if( isEnd() )
00163 {
00164 break;
00165 }
00166 else
00167 {
00168 next();
00169 }
00170 } while( !isInner() );
00171 }
00172
00173 protected:
00175 bool isInner()
00176 {
00177
00178 return (m_Impl.m_iCX1 * m_Impl.m_iInv1 <= 0
00179 && m_Impl.m_iCX2 * m_Impl.m_iInv2 <= 0
00180 && m_Impl.m_iCX3 * m_Impl.m_iInv3 <= 0);
00181 }
00182
00184 void init(tVolume *pVolume,
00185 vctl::MCPoint3D *p0,
00186 vctl::MCPoint3D *p1,
00187 vctl::MCPoint3D *p2
00188 )
00189 {
00190 MDS_ASSERT(p0 && p1 && p2 && pVolume);
00191
00192
00193 double dVertices[3][3];
00194 m_pScale->conv2Volume(p0, dVertices[0][0], dVertices[0][1], dVertices[0][2]);
00195 m_pScale->conv2Volume(p1, dVertices[1][0], dVertices[1][1], dVertices[1][2]);
00196 m_pScale->conv2Volume(p2, dVertices[2][0], dVertices[2][1], dVertices[2][2]);
00197
00198
00199 vctl::MCVector3D v01(dVertices[1][0] - dVertices[0][0],
00200 dVertices[1][1] - dVertices[0][1],
00201 dVertices[1][2] - dVertices[0][2]
00202 );
00203 vctl::MCVector3D v02(dVertices[2][0] - dVertices[0][0],
00204 dVertices[2][1] - dVertices[0][1],
00205 dVertices[2][2] - dVertices[0][2]
00206 );
00207 vctl::MCVector3D Normal(v01 % v02);
00208
00209
00210 double dPlane[4];
00211 dPlane[0] = Normal.GetX();
00212 dPlane[1] = Normal.GetY();
00213 dPlane[2] = Normal.GetZ();
00214 dPlane[3] = -dPlane[0] * dVertices[0][0];
00215 dPlane[3] -= dPlane[1] * dVertices[0][1];
00216 dPlane[3] -= dPlane[2] * dVertices[0][2];
00217
00218
00219 int iMapping[3] = { 0, 1, 2 };
00220 m_Impl.m_pX = &m_Impl.m_X;
00221 m_Impl.m_pY = &m_Impl.m_Y;
00222 m_Impl.m_pZ = &m_Impl.m_Z;
00223
00224
00225
00226
00227 if( mds::math::getAbs(dPlane[0]) > mds::math::getAbs(dPlane[1]) )
00228 {
00229 if( mds::math::getAbs(dPlane[0]) > mds::math::getAbs(dPlane[2]) )
00230 {
00231 mds::math::swap(iMapping[0], iMapping[2]);
00232 mds::math::swap(m_Impl.m_pX, m_Impl.m_pZ);
00233 }
00234 }
00235 else
00236 {
00237 if( mds::math::getAbs(dPlane[1]) > mds::math::getAbs(dPlane[2]) )
00238 {
00239 mds::math::swap(iMapping[1], iMapping[2]);
00240 mds::math::swap(m_Impl.m_pY, m_Impl.m_pZ);
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 double dInvC = -1.0 / dPlane[iMapping[2]];
00256 m_Impl.m_dDX = dPlane[iMapping[0]] * dInvC;
00257 m_Impl.m_dDY = dPlane[iMapping[1]] * dInvC;
00258
00259
00260
00261 int iY1 = mds::math::round2Int(16.0 * dVertices[0][iMapping[1]]);
00262 int iY2 = mds::math::round2Int(16.0 * dVertices[1][iMapping[1]]);
00263 int iY3 = mds::math::round2Int(16.0 * dVertices[2][iMapping[1]]);
00264
00265 int iX1 = mds::math::round2Int(16.0 * dVertices[0][iMapping[0]]);
00266 int iX2 = mds::math::round2Int(16.0 * dVertices[1][iMapping[0]]);
00267 int iX3 = mds::math::round2Int(16.0 * dVertices[2][iMapping[0]]);
00268
00269
00270 int iDX1 = iX2 - iX1;
00271 int iDX2 = iX3 - iX2;
00272 int iDX3 = iX1 - iX3;
00273
00274 int iDY1 = iY2 - iY1;
00275 int iDY2 = iY3 - iY2;
00276 int iDY3 = iY1 - iY3;
00277
00278
00279 m_Impl.m_iFDX1 = iDX1 << 4;
00280 m_Impl.m_iFDX2 = iDX2 << 4;
00281 m_Impl.m_iFDX3 = iDX3 << 4;
00282
00283 m_Impl.m_iFDY1 = iDY1 << 4;
00284 m_Impl.m_iFDY2 = iDY2 << 4;
00285 m_Impl.m_iFDY3 = iDY3 << 4;
00286
00287
00288 m_Impl.m_iMinX = mds::math::getMin(iX1, iX2, iX3) >> 4;
00289 m_Impl.m_iMaxX = mds::math::getMax(iX1, iX2, iX3) >> 4;
00290 m_Impl.m_iMinY = mds::math::getMin(iY1, iY2, iY3) >> 4;
00291 m_Impl.m_iMaxY = mds::math::getMax(iY1, iY2, iY3) >> 4;
00292
00293
00294 int iC1 = iDX1 * iY1 - iDY1 * iX1;
00295 int iC2 = iDX2 * iY2 - iDY2 * iX2;
00296 int iC3 = iDX3 * iY3 - iDY3 * iX3;
00297
00298
00299 m_Impl.m_iInv1 = 1;
00300 m_Impl.m_iInv2 = 1;
00301 m_Impl.m_iInv3 = 1;
00302 if( (iC1 - iDX1 * iY3 + iDY1 * iX3) > 0 )
00303 {
00304 m_Impl.m_iInv1 = -1;
00305 }
00306 if( (iC2 - iDX2 * iY1 + iDY2 * iX1) > 0 )
00307 {
00308 m_Impl.m_iInv2 = -1;
00309 }
00310 if( (iC3 - iDX3 * iY2 + iDY3 * iX2) > 0 )
00311 {
00312 m_Impl.m_iInv3 = -1;
00313 }
00314
00315
00316 m_Impl.m_iCY1 = iC1 - iDX1 * (m_Impl.m_iMinY << 4) + iDY1 * (m_Impl.m_iMinX << 4);
00317 m_Impl.m_iCY2 = iC2 - iDX2 * (m_Impl.m_iMinY << 4) + iDY2 * (m_Impl.m_iMinX << 4);
00318 m_Impl.m_iCY3 = iC3 - iDX3 * (m_Impl.m_iMinY << 4) + iDY3 * (m_Impl.m_iMinX << 4);
00319
00320 m_Impl.m_iCX1 = m_Impl.m_iCY1;
00321 m_Impl.m_iCX2 = m_Impl.m_iCY2;
00322 m_Impl.m_iCX3 = m_Impl.m_iCY3;
00323
00324 m_Impl.m_X = m_Impl.m_iMinX;
00325 m_Impl.m_Y = m_Impl.m_iMinY;
00326
00327
00328 m_Impl.m_dZ = dPlane[iMapping[0]] * m_Impl.m_iMinX;
00329 m_Impl.m_dZ += dPlane[iMapping[1]] * m_Impl.m_iMinY;
00330 m_Impl.m_dZ += dPlane[3];
00331 m_Impl.m_dZ *= dInvC;
00332 m_Impl.m_dY = m_Impl.m_dZ;
00333 m_Impl.m_Z = mds::math::round2Int(m_Impl.m_dZ);
00334
00335
00336 m_pContainer = pVolume;
00337 m_pItem = pVolume->getPtr(*m_Impl.m_pX, *m_Impl.m_pY, *m_Impl.m_pZ);
00338
00339
00340 if( !isInner() )
00341 {
00342 advance();
00343 }
00344 }
00345
00347 void next()
00348 {
00349 if( ++m_Impl.m_X > m_Impl.m_iMaxX )
00350 {
00351 m_Impl.m_X = m_Impl.m_iMinX;
00352 ++m_Impl.m_Y;
00353 m_Impl.m_iCY1 -= m_Impl.m_iFDX1;
00354 m_Impl.m_iCY2 -= m_Impl.m_iFDX2;
00355 m_Impl.m_iCY3 -= m_Impl.m_iFDX3;
00356 m_Impl.m_iCX1 = m_Impl.m_iCY1;
00357 m_Impl.m_iCX2 = m_Impl.m_iCY2;
00358 m_Impl.m_iCX3 = m_Impl.m_iCY3;
00359
00360 m_Impl.m_dY += m_Impl.m_dDY;
00361 m_Impl.m_dZ = m_Impl.m_dY;
00362 }
00363 else
00364 {
00365 m_Impl.m_iCX1 += m_Impl.m_iFDY1;
00366 m_Impl.m_iCX2 += m_Impl.m_iFDY2;
00367 m_Impl.m_iCX3 += m_Impl.m_iFDY3;
00368
00369 m_Impl.m_dZ += m_Impl.m_dDX;
00370 }
00371
00372 m_Impl.m_Z = mds::math::round2Int(m_Impl.m_dZ);
00373 m_pItem = m_pContainer->getPtr(*m_Impl.m_pX, *m_Impl.m_pY, *m_Impl.m_pZ);
00374 }
00375 };
00376
00377
00378 }
00379 }
00380
00381 #endif // MDS_TETRATRIITERATOR_H
00382