mdsTetraIterator.h

Go to the documentation of this file.
00001 //==============================================================================
00015 #ifndef MDS_TETRAITERATOR_H
00016 #define MDS_TETRAITERATOR_H
00017 
00018 #include "mdsTetraBase.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, CTetraIterator, seg::CTetraBase::tVoxel);
00034 
00035 namespace seg
00036 {
00037 
00038 //==============================================================================
00043 class CTetraIterator
00044     : public mds::base::CIteratorBase<CTetraIterator>
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     CTetraIterator(tVolume *pVolume, vctl::MCTetra *pTetrahedron, tScale *pScale)
00059         : m_pScale(pScale)
00060     {
00061         MDS_ASSERT(pScale);
00062         
00063         init(pVolume, pTetrahedron);
00064     }
00065 
00067     CTetraIterator(const CTetraIterator& It)
00068         : base(It)
00069         , m_pScale(It.m_pScale)
00070     {
00071         mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00072     }
00073 
00075     ~CTetraIterator() {}
00076 
00078     CTetraIterator& operator=(const CTetraIterator& It)
00079     {
00080         m_pContainer = It.m_pContainer;
00081         m_pItem = It.m_pItem;
00082         mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00083         m_pScale = It.m_pScale;
00084         return *this;
00085     }
00086 
00087 
00089     mds::tSize getX() const { return m_Impl.m_iX; }
00090     mds::tSize getY() const { return m_Impl.m_iY; }
00091     mds::tSize getZ() const { return m_Impl.m_iZ; }
00092 
00094     double getRealX() const { return m_pScale->getRealX(m_Impl.m_iX); }
00095     double getRealY() const { return m_pScale->getRealY(m_Impl.m_iY); }
00096     double getRealZ() const { return m_pScale->getRealZ(m_Impl.m_iZ); }
00097 
00100     bool isEnd() const { return (m_Impl.m_iZ > m_Impl.m_iMaxZ); }
00101 
00103     void advance()
00104     {
00105         do {
00106             if( isEnd() )
00107             {
00108                 break;
00109             }
00110             else
00111             {
00112                 next();
00113             }
00114         } while( !isInner() );
00115     }
00116 
00117 protected:
00119     struct SDataMembers
00120     {
00122         int m_iMinX, m_iMaxX, m_iMinY, m_iMaxY, m_iMinZ, m_iMaxZ;
00123 
00125         float m_fA[4], m_fB[4], m_fC[4], m_fD[4];
00126 
00128         float m_fEX[4], m_fEY[4], m_fEZ[4];
00129 
00131         int m_iX, m_iY, m_iZ;
00132     };
00133 
00135     SDataMembers m_Impl;
00136 
00138     tScale *m_pScale;
00139 
00140 protected:
00142     bool isInner()
00143     {
00144 /*        return (m_Impl.m_fEX[0] >= 0.0f
00145                 && m_Impl.m_fEX[1] >= 0.0f
00146                 && m_Impl.m_fEX[2] >= 0.0f
00147                 && m_Impl.m_fEX[3] >= 0.0f);*/
00148         return (m_Impl.m_fEX[0] > 0.0f
00149                 && m_Impl.m_fEX[1] > 0.0f
00150                 && m_Impl.m_fEX[2] > 0.0f
00151                 && m_Impl.m_fEX[3] > 0.0f);
00152     }
00153 
00155     void init(tVolume *pVolume, vctl::MCTetra *pTetrahedron)
00156     {
00157         MDS_ASSERT(pVolume && pTetrahedron);
00158 //        MDS_CHECK(pVolume && pTetrahedron && m_pScale, return);
00159 
00160         // Get all vertices
00161         vctl::MCVertex *pVertices[4];
00162         pTetrahedron->GetVerticeS(pVertices);
00163 
00164 //        MDS_LOG_NOTE(pVertices[0] << " " << pVertices[1] << " " << pVertices[2] << " " << pVertices[3]);
00165 
00166         // Scale all vertices
00167         vctl::MCPoint3D Vertices[4];
00168         int i;
00169         for( i = 0; i < 4; ++i )
00170         {
00171             Vertices[i].SetX(pVertices[i]->GetX());
00172             Vertices[i].SetY(pVertices[i]->GetY());
00173             Vertices[i].SetZ(pVertices[i]->GetZ());
00174             m_pScale->conv2Volume(&Vertices[i]);
00175         }
00176 
00177         // Bounding rectangle
00178         m_Impl.m_iMaxX = m_Impl.m_iMinX = mds::math::round2Int(Vertices[0].GetX());
00179         m_Impl.m_iMaxY = m_Impl.m_iMinY = mds::math::round2Int(Vertices[0].GetY());
00180         m_Impl.m_iMaxZ = m_Impl.m_iMinZ = mds::math::round2Int(Vertices[0].GetZ());
00181         for( i = 1; i < 4; ++i )
00182         {
00183             m_Impl.m_iMinX = mds::math::getMin(m_Impl.m_iMinX, mds::math::round2Int(Vertices[i].GetX()));
00184             m_Impl.m_iMaxX = mds::math::getMax(m_Impl.m_iMaxX, mds::math::round2Int(Vertices[i].GetX()));
00185             m_Impl.m_iMinY = mds::math::getMin(m_Impl.m_iMinY, mds::math::round2Int(Vertices[i].GetY()));
00186             m_Impl.m_iMaxY = mds::math::getMax(m_Impl.m_iMaxY, mds::math::round2Int(Vertices[i].GetY()));
00187             m_Impl.m_iMinZ = mds::math::getMin(m_Impl.m_iMinZ, mds::math::round2Int(Vertices[i].GetZ()));
00188             m_Impl.m_iMaxZ = mds::math::getMax(m_Impl.m_iMaxZ, mds::math::round2Int(Vertices[i].GetZ()));
00189         }
00190 
00191         // Compute normal vectors of all tetrahedron sides
00192         vctl::MCVector3D Normal;
00193         for( i = 0; i < 4; ++i )
00194         {
00195             // Get normal of the tetrahedron side
00196             pTetrahedron->GetNormal2(i, Normal);
00197             
00198             // Inverted conversion to the volume coordinates :)
00199             m_pScale->conv2Real(&Normal);
00200             
00201             m_Impl.m_fA[i] = float(Normal.GetX());
00202             m_Impl.m_fB[i] = float(Normal.GetY());
00203             m_Impl.m_fC[i] = float(Normal.GetZ());
00204         }
00205 
00206         MDS_LOG_NOTE("after normals");
00207 
00208         // Constant
00209         for( i = 0; i < 4; ++i )
00210         {
00211             m_Impl.m_fD[i]  = -m_Impl.m_fA[i] * float(Vertices[i].GetX());
00212             m_Impl.m_fD[i] -=  m_Impl.m_fB[i] * float(Vertices[i].GetY());
00213             m_Impl.m_fD[i] -=  m_Impl.m_fC[i] * float(Vertices[i].GetZ());
00214         }
00215 
00216         MDS_LOG_NOTE("after plane");
00217 
00218         // Starting point
00219         m_Impl.m_iX = m_Impl.m_iMinX;
00220         m_Impl.m_iY = m_Impl.m_iMinY;
00221         m_Impl.m_iZ = m_Impl.m_iMinZ;
00222 
00223         // Initialization
00224         for( i = 0; i < 4; ++i )
00225         {
00226             m_Impl.m_fEZ[i] = m_Impl.m_fD[i] + m_Impl.m_fA[i] * m_Impl.m_iX + m_Impl.m_fB[i] * m_Impl.m_iY + m_Impl.m_fC[i] * m_Impl.m_iZ;
00227             m_Impl.m_fEY[i] = m_Impl.m_fEX[i] = m_Impl.m_fEZ[i];
00228         }
00229 
00230         MDS_LOG_NOTE("after init");
00231 
00232         // Initialize pointer to the starting voxel
00233         m_pContainer = pVolume;
00234         m_pItem = pVolume->getPtr(m_Impl.m_iX, m_Impl.m_iY, m_Impl.m_iZ);
00235 
00236         // Find the first voxel in the tetrahedron
00237         if( !isInner() )
00238         {
00239             advance();
00240         }
00241     }
00242 
00244     void next()
00245     {
00246         ++m_pItem;
00247 
00248         if( ++m_Impl.m_iX > m_Impl.m_iMaxX )
00249         {
00250             m_Impl.m_iX = m_Impl.m_iMinX;
00251 
00252             if( ++m_Impl.m_iY > m_Impl.m_iMaxY )
00253             {
00254                 m_Impl.m_iY = m_Impl.m_iMinY;
00255                 ++m_Impl.m_iZ;
00256 
00257                 m_Impl.m_fEZ[0] += m_Impl.m_fC[0];
00258                 m_Impl.m_fEZ[1] += m_Impl.m_fC[1];
00259                 m_Impl.m_fEZ[2] += m_Impl.m_fC[2];
00260                 m_Impl.m_fEZ[3] += m_Impl.m_fC[3];
00261 
00262                 m_Impl.m_fEY[0] = m_Impl.m_fEZ[0];
00263                 m_Impl.m_fEY[1] = m_Impl.m_fEZ[1];
00264                 m_Impl.m_fEY[2] = m_Impl.m_fEZ[2];
00265                 m_Impl.m_fEY[3] = m_Impl.m_fEZ[3];
00266             }
00267             else
00268             {
00269                 m_Impl.m_fEY[0] += m_Impl.m_fB[0];
00270                 m_Impl.m_fEY[1] += m_Impl.m_fB[1];
00271                 m_Impl.m_fEY[2] += m_Impl.m_fB[2];
00272                 m_Impl.m_fEY[3] += m_Impl.m_fB[3];
00273             }
00274 
00275             m_Impl.m_fEX[0] = m_Impl.m_fEY[0];
00276             m_Impl.m_fEX[1] = m_Impl.m_fEY[1];
00277             m_Impl.m_fEX[2] = m_Impl.m_fEY[2];
00278             m_Impl.m_fEX[3] = m_Impl.m_fEY[3];
00279 
00280             m_pItem = m_pContainer->getPtr(m_Impl.m_iX, m_Impl.m_iY, m_Impl.m_iZ);
00281         }
00282         else
00283         {
00284             m_Impl.m_fEX[0] += m_Impl.m_fA[0];
00285             m_Impl.m_fEX[1] += m_Impl.m_fA[1];
00286             m_Impl.m_fEX[2] += m_Impl.m_fA[2];
00287             m_Impl.m_fEX[3] += m_Impl.m_fA[3];
00288         }
00289     }
00290 };
00291 
00292 
00293 } // namespace seg
00294 } // namespace mds
00295 
00296 #endif // MDS_TETRAITERATOR_H
00297 

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