00001 #include <stdlib.h>
00002 #include "glos.h"
00003 #include <GL/gl.h>
00004 #include <GL/glu.h>
00005
00006 #include <string.h>
00007 #include <dirent.h>
00008 #include <sys/stat.h>
00009
00010 #include "Volume.h"
00011 #include "VolSet.h"
00012 #include "TorstensFilters.h"
00013 #include "SimpleDefs.h"
00014
00015 #include "specfvr.h"
00016
00017 #define TEMP_PATH "./"
00018 #define SFVR_NCOMPONENTS 7
00019
00020 using namespace SpecFVRNS;
00021
00022
00023 void exit_fun()
00024 {
00025 cout <<"exit fun!"<<endl;
00026 }
00027
00028 vu1112118::vu1112118()
00029 {
00030
00031 m_Oversample = 1.0;
00032 m_ZeroPad = 1.0;
00033
00034
00035
00036
00037 m_Filter = new TorstensFilters(d0_c3_4ef);
00038 m_Volumes.setFilter(m_Filter);
00039
00040 m_TFunc.resize(SFVR_NCOMPONENTS+1,256);
00041 m_Relight = true;
00042 m_Camera = new vuCamera;
00043
00044
00045 m_DoSpectral = true;
00046 doSpectral(false);
00047 }
00048
00049 vu1112118::~vu1112118()
00050 {
00051 if (m_Camera != NULL) {
00052 delete m_Camera;
00053 m_Camera = NULL;
00054 }
00055 }
00056
00057 void vu1112118::reset_refine(void)
00058 {
00059 x_pass = x_pass_add;
00060 y_pass = y_pass_add;
00061 x_stop = 0;
00062 y_stop = 0;
00063
00064 refined = 0;
00065 m_Volumes.clearSlice();
00066 }
00068
00069 void vu1112118::setViewVectors(const vuVector& view,const vuVector& up,const vuVector& right)
00070 {
00071 #if 0
00072 m_XAxis = right;
00073 m_YAxis = up;
00074 m_ZAxis = view;
00075
00076 m_XStep = right;
00077 m_YStep = up;
00078
00079 m_XStep.makeUnit();
00080 m_YStep.makeUnit();
00081
00082 m_XStep *= (float)(m_ImageXSize / m_SliceXSize);
00083 m_YStep *= (float)(m_ImageYSize / m_SliceYSize);
00084
00085 updateShLight();
00086 m_Origin = m_Origin[0] * m_XAxis + m_Origin[1] * m_YAxis + m_Origin[2] * m_ZAxis;
00087 #else
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 #endif
00109 }
00110
00111 void vu1112118::render(void)
00112 {
00113 if (m_Volumes.m_Recomp) {
00114 if (refined) reset_refine();
00115 m_Volumes.setCamera(*m_Camera);
00116 m_Volumes.computeSlice(x_stop, y_stop, x_pass, y_pass);
00117 m_Volumes.m_Recomp = false;
00118 if(m_DoSpectral) updateSImage();
00119 }
00120 if(m_DoSpectral && m_Relight) {
00121 m_SImage.getRGBImage(m_Image);
00122 m_Relight = false;
00123 }
00124 glClear(GL_COLOR_BUFFER_BIT);
00125 glPixelZoom(m_SliceXScale, m_SliceYScale);
00126 if(m_DoSpectral)
00127 m_Image.blit();
00128 else {
00129 glRasterPos2i(0,0);
00130 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
00131 glColor3f(1.0f,1.0f,1.0f);
00132 glDrawPixels(m_Volumes[0]->getSliceWidth(),
00133 m_Volumes[0]->getSliceHeight(),
00134 GL_LUMINANCE,
00135 GL_FLOAT,
00136 m_Volumes[0]->getSliceData());
00137 }
00138 }
00139
00140 void vu1112118::updateSImage() {
00141 int c;
00142 for(c=0;c<m_Volumes.m_NVolumes;c++) {
00143 float *slice = m_Volumes[c]->getSliceData();
00144 int w=m_Volumes[c]->getSliceWidth();
00145 int h=m_Volumes[c]->getSliceHeight();
00146 int px,py;
00147 for(py=0;py<h;py++) {
00148 for(px=0;px<w;px++,slice++) {
00149 m_SImage.get_xy_data(px,py)[c] = *slice;
00150 }
00151 }
00152 }
00153 m_SImage.create_black_mask();
00154 m_Relight = true;
00155 }
00156
00157 void vu1112118::resize(int w, int h)
00158 {
00159 glViewport(0, 0, (GLsizei)w, (GLsizei)h);
00160 glMatrixMode(GL_PROJECTION);
00161 glLoadIdentity();
00162 gluOrtho2D(0, (GLsizei)w, 0, (GLsizei)h);
00163 glMatrixMode(GL_MODELVIEW);
00164 glLoadIdentity();
00165
00166 m_SliceXScale = (float)w/(float)m_Volumes[0]->getSliceWidth();
00167 m_SliceYScale = (float)h/(float)m_Volumes[0]->getSliceWidth();
00168
00169 m_ScreenWidth = w;
00170 m_ScreenHeight = h;
00171
00172 m_Image.init(w,h);
00173 m_SImage.init(w,h);
00174 }
00175
00176 bool vu1112118::keyboard(unsigned char key, int x, int y)
00177 {
00178 bool recam = false;
00179 switch(key)
00180 {
00181 case 27:
00182 cout <<"Hit ESC."<<endl;
00183 exit(0);
00184 break;
00185 case '4': m_Volumes.rotateSliceY(-3.0f);
00186 m_Volumes.m_Recomp = true; recam = true;
00187 break;
00188 case '6': m_Volumes.rotateSliceY(3.0f);
00189 m_Volumes.m_Recomp = true; recam = true;
00190 break;
00191 case '8': m_Volumes.rotateSliceX(3.0f);
00192 m_Volumes.m_Recomp = true; recam = true;
00193 break;
00194 case '2': m_Volumes.rotateSliceX(-3.0f);
00195 m_Volumes.m_Recomp = true; recam = true;
00196 break;
00197 case '7': m_Volumes.rotateSliceZ(-3.0f);
00198 m_Volumes.m_Recomp = true; recam = true;
00199 break;
00200 case '9': m_Volumes.rotateSliceZ(3.0f);
00201 m_Volumes.m_Recomp = true; recam = true;
00202 break;
00203 case 's':
00204 m_Scale *= 1.0f/0.95f;
00205 m_Volumes.setSliceScale(m_Scale);
00206 m_Volumes.m_Recomp = true; break;
00207 case 'x':
00208 m_Scale *= 0.95f;
00209 m_Volumes.setSliceScale(m_Scale);
00210 m_Volumes.m_Recomp = true; break;
00211 case 'a': m_Volumes[0]->writeImage(); break;
00212 case 'd':
00213 if (!m_Volumes.setFilter(++m_currFilter)) {
00214 cout << "No more filters" << endl;
00215 m_Volumes.setFilter(--m_currFilter);
00216 }
00217 m_Volumes.m_Recomp = true; break;
00218 case 'c':
00219 if (!m_Volumes.setFilter(--m_currFilter)) {
00220 cout << "No more filters" << endl;
00221 m_Volumes.setFilter(++m_currFilter);
00222 }
00223 m_Volumes.m_Recomp = true; break;
00224 case 'r':
00225 if (refined < num_div) {
00226 x_stop += x_pass_add;
00227 y_stop += y_pass_add;
00228
00229 if (refined == num_div - 1) {
00230 x_pass = m_Volumes[0]->getInternalSliceWidth() / 2 - x_stop;
00231 y_pass = m_Volumes[0]->getInternalSliceHeight() / 2 - y_stop;
00232 }
00233
00234 refined++;
00235 m_Volumes.computeSlice(x_stop, y_stop, x_pass, y_pass);
00236 updateSImage();
00237 }
00238 break;
00239 case '?':
00240 cout <<"Help:"<<endl;
00241 cout <<" r - refine (can be done multiple times)"<<endl;
00242 cout <<" c,d - toggle filter" << endl;
00243 break;
00244 default:
00245
00246 return false;
00247 break;
00248 }
00249 if(recam) {
00250 m_Volumes[0]->getCamera(*m_Camera);
00251 }
00252 return true;
00253 }
00254
00255 bool vu1112118::doTempFilesExist(string fileName) {
00256 FILE *fileStream;
00257
00258 fileStream = fopen(fileName.c_str(), "r");
00259 if (fileStream != NULL) {
00260 fclose(fileStream);
00261 return true;
00262 }
00263 else
00264 return false;
00265 }
00266
00267 void vu1112118::ensureTempDirectory() {
00268 DIR *tmpDir;
00269
00270 tmpDir = opendir(TEMP_PATH);
00271 if (tmpDir == NULL) {
00272 cerr << "createDirectory +++++++++++++++++++++++++++++++++++++++" << endl;
00273 #ifdef WIN32
00274 mkdir(TEMP_PATH);
00275 #else
00276 mkdir(TEMP_PATH,
00277 S_IRUSR | S_IWUSR | S_IXUSR |
00278 S_IRGRP | S_IWGRP | S_IXGRP |
00279 S_IROTH | S_IWOTH | S_IXOTH);
00280 #endif
00281 }
00282 else
00283 closedir(tmpDir);
00284 }
00285
00286 bool vu1112118::read()
00287 {
00288 m_currFilter = 0;
00289 string myFile(this->getFileName());
00290
00291 unsigned int len = myFile.length();
00292 unsigned int pos = myFile.rfind("/", len);
00293
00294 if ((pos != string::npos) && (pos < len)) {
00295 myFile = myFile.substr(pos+1, len);
00296 }
00297 len = myFile.length();
00298
00299 if (len >4) {
00300 myFile.replace(len-4, len, "0.fvr");
00301 myFile = string(TEMP_PATH) + myFile;
00302
00303 cerr << "myFile is " << myFile << endl;
00304
00305 if (!this->doTempFilesExist(myFile)) {
00306 bool success = vu111211::read();
00307 if (!success) return false;
00308
00309 cerr << "x=" << m_Dim1Size << "y=" << m_Dim2Size << "z=" << m_Dim3Size;
00310 cerr << endl;
00311
00312 this->ensureTempDirectory();
00313
00314 preprocess();
00315
00316
00317
00318 }
00319
00320 #if 0
00321 char *fname = (char *)myFile.c_str();
00322
00323 cout << "PROCESSING " << fname << endl;
00324
00325 bool ret = m_Volumes.read(fname, m_Oversample, m_ZeroPad);
00326
00327 cout << "FINISHED PROCESSING" << endl;
00328
00329 if (!ret) {
00330 cout << "bad file\n";
00331 return false;
00332 }
00333 #endif
00334 }
00335
00336 cout << "slice width " << m_Volumes[0]->getSliceWidth()<< endl;
00337 return true;
00338 }
00339
00340 bool vu1112118::readRaw(void)
00341 {
00342 #if 0
00343 dword len;
00344 ifstream in;
00345
00346 cerr << "+++++++++++++ rawRead is called" << endl;
00347
00348 #ifdef IS_NOCREATE_NEEDED
00349 in.open(m_FileName, ios::in|ios::binary|ios::nocreate);
00350 #else
00351
00352
00353 in.open(m_FileName, ios::in|ios::binary);
00354 #endif
00355 if (!in.is_open()) return false;
00356
00357 in.seekg(0, ios::end);
00358 len = in.tellg();
00359 in.seekg(0, ios::beg);
00360
00361 in >> m_Dim1Size >> m_Dim2Size >> m_Dim3Size;
00362 if (in.fail()) return false;
00363 m_DataSize = m_Dim1Size*m_Dim2Size*m_Dim3Size;
00364
00365 m_Data = new byte[m_DataSize];
00366 in.read((char *) (m_Data), int (m_DataSize));
00367 if (in.fail()) return false;
00368
00369 in.close();
00370
00371 preprocess();
00372 #endif
00373
00374 return true;
00375 }
00376
00377 void vu1112118::preprocess()
00378 {
00379
00380 m_Volumes.setFilter(m_currFilter);
00381 m_TFunc.normalizeAlphaToOne();
00382 m_Volumes.buildColourVolumes(m_Data,
00383 m_Dim1Size, m_Dim2Size, m_Dim3Size,
00384 sizeof(byte), m_TFunc,
00385 m_Oversample, m_ZeroPad);
00386 m_Volumes.setFilter(m_currFilter);
00387
00388 m_Scale = 8.0f/(float)m_Volumes[0]->getInternalSliceWidth();
00389 m_Volumes.setSliceScale(m_Scale);
00390
00391 num_div = 4;
00392 x_pass_add = m_Volumes[0]->getInternalSliceWidth() / num_div / 2;
00393 y_pass_add = m_Volumes[0]->getInternalSliceHeight() / num_div / 2;
00394 reset_refine();
00395 refined = false;
00396
00397 m_Volumes.m_Recomp = true;
00398
00399 m_ScreenWidth = m_Volumes[0]->getSliceWidth()*2;
00400 m_ScreenHeight = m_Volumes[0]->getSliceHeight()*2;
00401 }
00402
00403 void vu1112118::write_fvr(char* out)
00404 {
00405 cerr << "Writing transformed volume to files...\n";
00406
00407 m_Volumes.write_fvr(out);
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 }
00443
00444 void vu1112118::setLight(const vuColour31a& light)
00445 {
00446 m_SImage.set_light(vuColour7a(light));
00447 m_Relight = true;
00448 }
00449
00450 void vu1112118::doSpectral(bool doit)
00451 {
00452 if((m_DoSpectral && doit) || (!m_DoSpectral && !doit)) return;
00453 m_DoSpectral = doit;
00454 if(m_DoSpectral) {
00455 m_TFunc.resize(SFVR_NCOMPONENTS+1,256);
00456 } else {
00457 m_TFunc.resize(2,256);
00458 m_TFunc.fromMap(vuMap());
00459 }
00460 }