Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

specfvr.cpp

Go to the documentation of this file.
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 // a friend who does nothing
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     //atexit(exit_fun);
00035 
00036     //m_Volumes.reset(NCOMP);
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     //by default just do conventional FVR
00044     //that means, unmapped intensities are transformed, single channel
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   m_XAxis  = right;
00090   m_YAxis  = up;
00091   m_ZAxis  = view;
00092 
00093   m_XAxis.makeUnit();
00094   m_YAxis.makeUnit();
00095   m_ZAxis.makeUnit();
00096 
00097   m_XStep  = m_XAxis;
00098   m_YStep  = m_YAxis;
00099   
00100   m_XStep *= (float)(m_ImageXSize / m_SliceXSize);
00101   m_YStep *= (float)(m_ImageYSize / m_SliceYSize);
00102 
00103   updateShLight();
00104   m_Origin = -1 * (0.5*m_XAxis*m_SliceXSize+0.5*m_YAxis*m_SliceYSize+0.5*m_ZAxis*m_SliceYSize);
00105 
00106   //m_Origin = m_Origin[0] * m_XAxis + m_Origin[1] * m_YAxis + m_Origin[2] * m_ZAxis;
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             //cout<<"Press '?' for Help"<<endl;
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) { // myFile must contain at least the file extension
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       //TODO: all should be written, not just one
00317       //write_fvr((char *)myFile.c_str());
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   // The nocreate is not available on the IRIX boxes that we were compiling
00352   // this code on, so we had to remove this part from
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     //convert the byte .vud volume to frequency volumes
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   int len = strlen(out) + 1;
00410   char *out = new char[len];
00411   memset(out, 0, len);
00412   strcpy(out, fileName);
00413 
00414   for(int yl = 0; yl < VOLUME_MAX_NUM; yl++)
00415     {
00416       ofstream fout;
00417       out[len - 6] = char('0' + yl);
00418       cerr << out << endl;
00419       fout.open(out, ios::out|ios::binary);
00420       write_fvr_head(fout, m_Dim1Size, m_Dim2Size, m_Dim3Size, sizeof(t_data));
00421 #ifdef SOLARIS
00422       fout.write((char*)&m_Yarray[yl][0], m_Dim1Size * m_Dim2Size * m_Dim3Size * 2 * sizeof(t_data));
00423 #else
00424       fout.write((byte*)&m_Yarray[yl][0], m_Dim1Size * m_Dim2Size * m_Dim3Size * 2 * sizeof(t_data));
00425 #endif
00426       
00427       fout.flush();
00428       fout.close();
00429     }
00430 */
00431   
00432   /*nasty bug, forgot to comment!
00433     ofstream fout;
00434     fout.open(out, ios::out|ios::binary);
00435     
00436     write_fvr_head(fout, m_Dim1Size, m_Dim2Size, m_Dim3Size, sizeof(t_data));
00437     fout.write((byte*)m_Volume, m_Dim1Size * m_Dim2Size * m_Dim3Size * 2 * sizeof(t_data));
00438     
00439     fout.close();
00440   */
00441   // delete out;
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());       //is identity by default
00459     }
00460 }

Generated on Wed Dec 15 21:20:31 2004 for vuVolume by  doxygen 1.3.9.1