00001 #pragma once
00002
00003 #include "common.h"
00004 #include <stdlib.h>
00005 #include <glew.h>
00006 #include <vector>
00007
00008 #include <algorithm>
00009 #include <functional>
00010
00011 #include "Matrix.h"
00012
00018 class Volume
00019 {
00020 public:
00021
00027 class Voxel
00028 {
00029 public:
00030
00031 Voxel()
00032 {
00033 SetValue(0.0f);
00034 };
00035
00036 Voxel(const Voxel & datOther)
00037 {
00038 m_fValue = datOther.m_fValue;
00039 };
00040
00041 Voxel(const float fValue)
00042 {
00043 SetValue(fValue);
00044 };
00045
00046
00047 ~Voxel()
00048 {
00049 };
00050
00051 void SetValue(const float fValue)
00052 {
00053 m_fValue = fValue;
00054 };
00055
00056 const float GetValue() const
00057 {
00058 return m_fValue;
00059 };
00060
00061 const bool operator==(const Voxel &datOther) const
00062 {
00063 return (GetValue() == datOther.GetValue());
00064 };
00065
00066 const bool operator!=(const Voxel &datOther) const
00067 {
00068 return !(*this == datOther);
00069 };
00070
00071 const bool operator>(const Voxel &datOther) const
00072 {
00073 return GetValue() > datOther.GetValue();
00074 };
00075
00076 const bool operator>=(const Voxel &datOther) const
00077 {
00078 return GetValue() >= datOther.GetValue();
00079 };
00080
00081 const bool operator<(const Voxel &datOther) const
00082 {
00083 return GetValue() < datOther.GetValue();
00084 };
00085
00086 const bool operator<=(const Voxel &datOther) const
00087 {
00088 return GetValue() <= datOther.GetValue();
00089 };
00090
00091 const Voxel & operator+=(const Voxel & datOther)
00092 {
00093 m_fValue += datOther.m_fValue;
00094 return *this;
00095 };
00096
00097 const Voxel & operator-=(const Voxel & datOther)
00098 {
00099 m_fValue -= datOther.m_fValue;
00100 return *this;
00101 };
00102
00103 const Voxel & operator*=(const float & fOther)
00104 {
00105 m_fValue *= fOther;
00106 return *this;
00107 };
00108
00109 const Voxel & operator/=(const float & fOther)
00110 {
00111 m_fValue /= fOther;
00112 return *this;
00113 };
00114
00115 const Voxel operator+(const Voxel & datOther) const
00116 {
00117 Voxel voxNew = *this;
00118 voxNew += datOther;
00119 return voxNew;
00120 };
00121
00122 const Voxel operator-(const Voxel & datOther) const
00123 {
00124 Voxel voxNew = *this;
00125 voxNew -= datOther;
00126 return voxNew;
00127 };
00128
00129 const Voxel operator*(const float & fOther) const
00130 {
00131 Voxel voxNew = *this;
00132 voxNew *= fOther;
00133 return voxNew;
00134 };
00135
00136 const Voxel operator/(const float & fOther) const
00137 {
00138 Voxel voxNew = *this;
00139 voxNew /= fOther;
00140 return voxNew;
00141 };
00142
00143 private:
00144 float m_fValue;
00145 };
00146
00147 struct Gradient{
00148 float x;
00149 float y;
00150 float z;
00151 };
00152 public:
00153 Volume() : m_iWidth(1), m_iHeight(1), m_iDepth(1), m_vecVoxels(1),m_gradients(1)
00154 {
00155 };
00156
00157 Volume(const std::string &strFilename) : m_iWidth(1), m_iHeight(1), m_iDepth(1), m_vecVoxels(1), m_gradients(1)
00158 {
00159 load(strFilename);
00160 };
00161
00162 ~Volume(void)
00163 {
00164 };
00165
00166 const Voxel & Get(const int iX, const int iY, const int iZ) const
00167 {
00168 return m_vecVoxels[iX + iY*m_iWidth + iZ*m_iWidth*m_iHeight];
00169 };
00170
00171 const Voxel & Get(const int iIndex) const
00172 {
00173 return m_vecVoxels[iIndex];
00174 };
00175
00176 const Voxel * Get() const
00177 {
00178 return &(m_vecVoxels.front());
00179 };
00180
00181 const Vector * GetGradient() const
00182 {
00183 return &(m_gradients.front());
00184 };
00185 const int GetWidth() const
00186 {
00187 return m_iWidth;
00188 };
00189
00190 const int GetHeight() const
00191 {
00192 return m_iHeight;
00193 };
00194
00195 const int GetDepth() const
00196 {
00197 return m_iDepth;
00198 };
00199
00200 const int GetSize() const
00201 {
00202 return int(m_vecVoxels.size());
00203 };
00204
00212 void load(const std::string & strFilename)
00213 {
00214 std::cout << "- Loading file '" << strFilename << "' ... " << std::endl;
00215 FILE *fp = NULL;
00216
00217 fopen_s(&fp,strFilename.c_str(),"rb");
00218
00219 if (!fp)
00220 {
00221 std::cerr << "+ Error loading file." << std::endl << std::endl;
00222 }
00223 else
00224 {
00225 unsigned short uWidth, uHeight, uDepth;
00226 fread(&uWidth,sizeof(unsigned short),1,fp);
00227 fread(&uHeight,sizeof(unsigned short),1,fp);
00228 fread(&uDepth,sizeof(unsigned short),1,fp);
00229
00230 m_iWidth = int(uWidth);
00231 m_iHeight = int(uHeight);
00232 m_iDepth = int(uDepth);
00233
00234 const int iSlice = m_iWidth * m_iHeight;
00235 const int iSize = iSlice * m_iDepth;
00236 m_vecVoxels.resize(iSize);
00237
00238 std::vector<unsigned short> vecData;
00239 vecData.resize(iSize);
00240
00241 fread((void*)&(vecData.front()),sizeof(unsigned short),iSize,fp);
00242 fclose(fp);
00243
00244 std::cout << "- File loaded." << std::endl;
00245
00246 for (int k=0;k<m_iDepth;k++)
00247 {
00248 for (int j=0;j<m_iHeight;j++)
00249 {
00250 for (int i=0;i<m_iWidth;i++)
00251 {
00252
00253 const float fValue = min(1.0f,float(vecData[i + j*m_iWidth + k*iSlice]) / 4095.0f);
00254 m_vecVoxels[i+j*m_iWidth+k*iSlice] = Voxel(fValue);
00255 }
00256 }
00257 std::cout << "\r- Preparing data (" << (k*100) / (m_iDepth-1) << "%) ...";
00258 }
00259 std::cout << std::endl << "- Data prepared." << std::endl;
00260
00261 m_gradients.resize(iSize);
00262 int count = 0;
00263 for (int k=0;k<m_iDepth;k++)
00264 {
00265 for (int j=0;j<m_iHeight;j++)
00266 {
00267 for (int i=0;i<m_iWidth;i++)
00268 {
00269
00270
00271 int i0 = i+1 < m_iWidth ? i+1 : i; int i1 = i-1 >= 0 ? i-1 : i;
00272 int j0 = j+1 < m_iHeight ? j+1 : j; int j1 = j-1 >= 0 ? j-1 : j;
00273 int k0 = k+1 < m_iDepth ? k+1 : k; int k1 = k-1 >= 0 ? k-1 : k;
00274
00275 m_gradients[i+j*m_iWidth+k*iSlice].SetX(1.f/2.f * (Get(i0,j,k).GetValue()-Get(i1,j,k).GetValue()));
00276 m_gradients[i+j*m_iWidth+k*iSlice].SetY(1.f/2.f * (Get(i,j0,k).GetValue()-Get(i,j1,k).GetValue()));
00277 m_gradients[i+j*m_iWidth+k*iSlice].SetZ(1.f/2.f * (Get(i,j,k0).GetValue()-Get(i,j,k1).GetValue()));
00278
00279
00280
00281
00282
00283 if(m_gradients[i+j*m_iWidth+k*iSlice].GetX() < 0)
00284 count++;
00285
00286 if(m_gradients[i+j*m_iWidth+k*iSlice].GetY() < 0)
00287 count++;
00288
00289 if(m_gradients[i+j*m_iWidth+k*iSlice].GetX() < 0)
00290 count++;
00291 m_gradients[i+j*m_iWidth+k*iSlice].normalize();
00292
00293 m_gradients[i+j*m_iWidth+k*iSlice].SetX(m_gradients[i+j*m_iWidth+k*iSlice].GetX()/2.f+0.5f);
00294 m_gradients[i+j*m_iWidth+k*iSlice].SetY(m_gradients[i+j*m_iWidth+k*iSlice].GetY()/2.f+0.5f);
00295 m_gradients[i+j*m_iWidth+k*iSlice].SetZ(m_gradients[i+j*m_iWidth+k*iSlice].GetZ()/2.f+0.5f);
00296 }
00297 }
00298 std::cout << "\r- Calculating gradient (" << (k*100) / (m_iDepth-1) << "%) ...";
00299 }
00300
00301 }
00302 };
00303
00304 protected:
00305
00306
00307 private:
00308 std::vector<Voxel> m_vecVoxels;
00309 std::vector<Vector> m_gradients;
00310 int m_iWidth,m_iHeight,m_iDepth;
00311 };