00001
00015 #ifndef MDS_TETRAITERATOR_H
00016 #define MDS_TETRAITERATOR_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, 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
00145
00146
00147
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
00159
00160
00161 vctl::MCVertex *pVertices[4];
00162 pTetrahedron->GetVerticeS(pVertices);
00163
00164
00165
00166
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
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
00192 vctl::MCVector3D Normal;
00193 for( i = 0; i < 4; ++i )
00194 {
00195
00196 pTetrahedron->GetNormal2(i, Normal);
00197
00198
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
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
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
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
00233 m_pContainer = pVolume;
00234 m_pItem = pVolume->getPtr(m_Impl.m_iX, m_Impl.m_iY, m_Impl.m_iZ);
00235
00236
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 }
00294 }
00295
00296 #endif // MDS_TETRAITERATOR_H
00297