00001
00015 #ifndef MDS_TETRAEDGEITERATOR_H
00016 #define MDS_TETRAEDGEITERATOR_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 #include <MDSTk/Image/mdsVector3.h>
00025
00026
00027 #include <VectorEntity/mcentity.h>
00028
00029
00030 namespace mds
00031 {
00032
00033
00034 MDS_ITERATOR_TRAITS(seg, CTetraEdgeIterator, seg::CTetraBase::tVoxel);
00035 MDS_ITERATOR_TRAITS(seg, CTetraEdgeDDAIterator, seg::CTetraBase::tVoxel);
00036
00037 namespace seg
00038 {
00039
00040
00045 class CTetraEdgeIterator
00046 : public mds::base::CIteratorBase<CTetraEdgeIterator>
00047 , public mds::base::CContainerHolder<CTetraBase::tVolume, CTetraBase::tVoxel>
00048 {
00049 public:
00051 typedef mds::base::CContainerHolder<CTetraBase::tVolume, CTetraBase::tVoxel> base;
00052
00054 typedef CTetraBase::tVolume tVolume;
00055 typedef CTetraBase::tVoxel tVoxel;
00056 typedef CTetraBase::tScale tScale;
00057
00058 public:
00060 CTetraEdgeIterator(tVolume *pVolume, vctl::MCEdge *pEdge, tScale *pScale)
00061 : m_pScale(pScale)
00062 {
00063 MDS_ASSERT(pScale && pEdge);
00064
00065
00066 vctl::MCVertex *pVertices[2];
00067 pEdge->GetVerticeS(pVertices);
00068
00069 init(pVolume, pVertices[0], pVertices[1]);
00070 }
00071
00073 CTetraEdgeIterator(tVolume *pVolume,
00074 vctl::MCPoint3D *p1,
00075 vctl::MCPoint3D *p2,
00076 tScale *pScale
00077 )
00078 : m_pScale(pScale)
00079 {
00080 MDS_ASSERT(pScale);
00081
00082 init(pVolume, p1, p2);
00083 }
00084
00086 CTetraEdgeIterator(const CTetraEdgeIterator& It)
00087 : base(It)
00088 , m_pScale(It.m_pScale)
00089 {
00090 mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00091 }
00092
00094 ~CTetraEdgeIterator() {}
00095
00097 CTetraEdgeIterator& operator=(const CTetraEdgeIterator& It)
00098 {
00099 base::m_pContainer = It.m_pContainer;
00100 base::m_pItem = It.m_pItem;
00101 mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00102 m_pScale = It.m_pScale;
00103 return *this;
00104 }
00105
00106
00108 mds::tSize getX() const { return *m_Impl.m_pX; }
00109 mds::tSize getY() const { return *m_Impl.m_pY; }
00110 mds::tSize getZ() const { return *m_Impl.m_pZ; }
00111
00113 double getRealX() const { return m_pScale->getRealX(*m_Impl.m_pX); }
00114 double getRealY() const { return m_pScale->getRealY(*m_Impl.m_pY); }
00115 double getRealZ() const { return m_pScale->getRealZ(*m_Impl.m_pZ); }
00116
00118 bool isEnd() const { return (m_Impl.m_X > m_Impl.m_MaxX); }
00119
00120 protected:
00122 struct SDataMembers
00123 {
00125 mds::tSize m_StepY, m_StepZ;
00126
00128 mds::tSize m_K1Y, m_K2Y, m_PY;
00129 mds::tSize m_K1Z, m_K2Z, m_PZ;
00130
00132 mds::tSize m_MaxX;
00133
00135 mds::tSize m_X, m_Y, m_Z;
00136
00138 mds::tSize *m_pX, *m_pY, *m_pZ;
00139 };
00140
00142 SDataMembers m_Impl;
00143
00145 tScale *m_pScale;
00146
00147 public:
00149 void advance()
00150 {
00151 if( isEnd() )
00152 {
00153 return;
00154 }
00155
00156 ++m_Impl.m_X;
00157
00158 if( m_Impl.m_PY < 0 )
00159 {
00160 m_Impl.m_PY += m_Impl.m_K1Y;
00161 }
00162 else
00163 {
00164 m_Impl.m_PY += m_Impl.m_K2Y;
00165 m_Impl.m_Y += m_Impl.m_StepY;
00166 }
00167
00168 if( m_Impl.m_PZ < 0 )
00169 {
00170 m_Impl.m_PZ += m_Impl.m_K1Z;
00171 }
00172 else
00173 {
00174 m_Impl.m_PZ += m_Impl.m_K2Z;
00175 m_Impl.m_Z += m_Impl.m_StepZ;
00176 }
00177
00178 m_pItem = m_pContainer->getPtr(*m_Impl.m_pX, *m_Impl.m_pY, *m_Impl.m_pZ);
00179 }
00180
00181 protected:
00183 void init(tVolume *pVolume, vctl::MCPoint3D *p1, vctl::MCPoint3D *p2)
00184 {
00185 MDS_ASSERT(pVolume && p1 && p2);
00186
00187
00188 int iX1, iY1, iZ1, iX2, iY2, iZ2;
00189 m_pScale->conv2Volume(p1, iX1, iY1, iZ1);
00190 m_pScale->conv2Volume(p2, iX2, iY2, iZ2);
00191
00192
00193 int iDX = mds::math::getAbs(iX2 - iX1);
00194 int iDY = mds::math::getAbs(iY2 - iY1);
00195 int iDZ = mds::math::getAbs(iZ2 - iZ1);
00196
00197
00198 if( iDY >= iDX && iDY >= iDZ )
00199 {
00200 m_Impl.m_pX = &m_Impl.m_Y;
00201 m_Impl.m_pY = &m_Impl.m_X;
00202 m_Impl.m_pZ = &m_Impl.m_Z;
00203
00204 mds::math::swap(iX1, iY1);
00205 mds::math::swap(iX2, iY2);
00206 mds::math::swap(iDX, iDY);
00207 }
00208 else if ( iDZ >= iDX && iDZ >= iDY )
00209 {
00210 m_Impl.m_pX = &m_Impl.m_Z;
00211 m_Impl.m_pY = &m_Impl.m_Y;
00212 m_Impl.m_pZ = &m_Impl.m_X;
00213
00214 mds::math::swap(iX1, iZ1);
00215 mds::math::swap(iX2, iZ2);
00216 mds::math::swap(iDX, iDZ);
00217 }
00218 else
00219 {
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 if( iX1 > iX2 )
00227 {
00228 mds::math::swap(iX1, iX2);
00229 mds::math::swap(iY1, iY2);
00230 mds::math::swap(iZ1, iZ2);
00231 }
00232
00233
00234 if( iY1 > iY2 )
00235 {
00236 m_Impl.m_StepY = -1;
00237 }
00238 else
00239 {
00240 m_Impl.m_StepY = 1;
00241 }
00242
00243 if( iZ1 > iZ2 )
00244 {
00245 m_Impl.m_StepZ = -1;
00246 }
00247 else
00248 {
00249 m_Impl.m_StepZ = 1;
00250 }
00251
00252
00253 m_Impl.m_K1Y = 2 * iDY;
00254 m_Impl.m_K2Y = 2 * (iDY - iDX);
00255 m_Impl.m_PY = 2 * iDY - iDX;
00256
00257 m_Impl.m_K1Z = 2 * iDZ;
00258 m_Impl.m_K2Z = 2 * (iDZ - iDX);
00259 m_Impl.m_PZ = 2 * iDZ - iDX;
00260
00261
00262 m_Impl.m_X = iX1;
00263 m_Impl.m_Y = iY1;
00264 m_Impl.m_Z = iZ1;
00265
00266
00267 m_Impl.m_MaxX = iX2;
00268
00269
00270 m_pContainer = pVolume;
00271
00272
00273 m_pItem = pVolume->getPtr(*m_Impl.m_pX, *m_Impl.m_pY, *m_Impl.m_pZ);
00274 }
00275 };
00276
00277
00278
00283 class CTetraEdgeDDAIterator
00284 : public mds::base::CIteratorBase<CTetraEdgeDDAIterator>
00285 , public mds::base::CContainerHolder<CTetraBase::tVolume, CTetraBase::tVoxel>
00286 {
00287 public:
00289 typedef mds::base::CContainerHolder<CTetraBase::tVolume, CTetraBase::tVoxel> base;
00290
00292 typedef CTetraBase::tVolume tVolume;
00293 typedef CTetraBase::tVoxel tVoxel;
00294 typedef CTetraBase::tScale tScale;
00295
00296 public:
00298 CTetraEdgeDDAIterator(tVolume *pVolume, vctl::MCEdge *pEdge, tScale *pScale)
00299 : m_pScale(pScale)
00300 {
00301 MDS_ASSERT(pScale && pEdge);
00302
00303
00304 vctl::MCVertex *pVertices[2];
00305 pEdge->GetVerticeS(pVertices);
00306
00307 init(pVolume, pVertices[0], pVertices[1]);
00308 }
00309
00311 CTetraEdgeDDAIterator(tVolume *pVolume,
00312 vctl::MCPoint3D *p1,
00313 vctl::MCPoint3D *p2,
00314 tScale *pScale
00315 )
00316 : m_pScale(pScale)
00317 {
00318 MDS_ASSERT(pScale);
00319
00320 init(pVolume, p1, p2);
00321 }
00322
00324 CTetraEdgeDDAIterator(const CTetraEdgeDDAIterator& It)
00325 : base(It)
00326 , m_pScale(It.m_pScale)
00327 {
00328 mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00329 }
00330
00332 ~CTetraEdgeDDAIterator() {}
00333
00335 CTetraEdgeDDAIterator& operator=(const CTetraEdgeDDAIterator& It)
00336 {
00337 base::m_pContainer = It.m_pContainer;
00338 base::m_pItem = It.m_pItem;
00339 mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00340 m_pScale = It.m_pScale;
00341 return *this;
00342 }
00343
00344
00346 mds::tSize getX() const { return mds::math::round2Int(m_Impl.m_Position.getX()); }
00347 mds::tSize getY() const { return mds::math::round2Int(m_Impl.m_Position.getY()); }
00348 mds::tSize getZ() const { return mds::math::round2Int(m_Impl.m_Position.getZ()); }
00349
00351 double getRealX() const { return m_pScale->getRealX(m_Impl.m_Position.getX()); }
00352 double getRealY() const { return m_pScale->getRealY(m_Impl.m_Position.getY()); }
00353 double getRealZ() const { return m_pScale->getRealZ(m_Impl.m_Position.getZ()); }
00354
00356
00357 bool isEnd() const { return mds::math::getAbs(m_Impl.m_Position.getX() - m_Impl.m_dMaxX) < 1.0; }
00358
00359 protected:
00361 struct SDataMembers
00362 {
00364 mds::img::CVector3D m_Step;
00365
00367 mds::img::CPoint3D m_Position;
00368
00370 double m_dMaxX;
00371
00373 tVoxel m_Value;
00374 };
00375
00377 SDataMembers m_Impl;
00378
00380 tScale *m_pScale;
00381
00382 public:
00384 void advance()
00385 {
00386 if( isEnd() )
00387 {
00388 return;
00389 }
00390
00391
00392 m_Impl.m_Position.x() += m_Impl.m_Step.x();
00393 m_Impl.m_Position.y() += m_Impl.m_Step.y();
00394 m_Impl.m_Position.z() += m_Impl.m_Step.z();
00395
00396
00397 m_Impl.m_Value = m_pContainer->interpolate(m_Impl.m_Position);
00398 }
00399
00400 protected:
00402 void init(tVolume *pVolume, vctl::MCPoint3D *p1, vctl::MCPoint3D *p2)
00403 {
00404 MDS_ASSERT(pVolume && p1 && p2);
00405
00406
00407 int iX1, iY1, iZ1, iX2, iY2, iZ2;
00408 m_pScale->conv2Volume(p1, iX1, iY1, iZ1);
00409 m_pScale->conv2Volume(p2, iX2, iY2, iZ2);
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 m_Impl.m_Step.setX(iX2 - iX1);
00421 m_Impl.m_Step.setY(iY2 - iY1);
00422 m_Impl.m_Step.setZ(iZ2 - iZ1);
00423
00424
00425
00426
00427
00428
00429
00430 double dX = mds::math::getAbs(m_Impl.m_Step.getX());
00431 double dY = mds::math::getAbs(m_Impl.m_Step.getY());
00432 double dZ = mds::math::getAbs(m_Impl.m_Step.getZ());
00433
00434 double dMax = mds::math::getMax(dX, dY, dZ);
00435 if( dMax < 1.0 )
00436 {
00437 m_Impl.m_Step.setX(1.0);
00438 m_Impl.m_Step.setY(1.0);
00439 m_Impl.m_Step.setZ(1.0);
00440 }
00441 else
00442 {
00443 double dInvMax = 1.0 / dMax;
00444 m_Impl.m_Step *= dInvMax;
00445 }
00446
00447
00448 m_Impl.m_Position.setX(iX1);
00449 m_Impl.m_Position.setY(iY1);
00450 m_Impl.m_Position.setZ(iZ1);
00451
00452
00453 m_Impl.m_dMaxX = iX2;
00454
00455
00456 m_pContainer = pVolume;
00457 m_pItem = &(m_Impl.m_Value);
00458
00459
00460 m_Impl.m_Value = m_pContainer->interpolate(m_Impl.m_Position);
00461 }
00462 };
00463
00464
00465 }
00466 }
00467
00468 #endif // MDS_TETRAEDGEITERATOR_H
00469