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

vuSimpleFBR.cpp

Go to the documentation of this file.
00001 #include "vuSimpleFBR.h"
00002 #include "Volume/Lightfield/Unimodal/Spheric/vuSphericFilterFactory.h"
00003 #include "General/vuLightfield/vuSphericViewFilterFactory.h"
00004 #include "../../../wxUIElements/vuSimpleProgressHandler.h"
00005 
00006 #include <wx/checklst.h>
00007 
00008 #define MAX_SLICE_FILTER_SIZE 6
00009 
00010 template <int S, class T>
00011 vuSimpleFBR<S,T>::vuSimpleFBR()
00012 {
00013   m_Data          = NULL;
00014   m_FourierFilter = NULL;
00015   m_SliceFilter   = NULL;
00016   m_Image         = NULL;
00017   m_Interactive   = NULL;
00018 
00019   m_CHOICEfilter               = NULL;
00020   m_TEXTfilterHint             = NULL;
00021   m_CHOICEfourierFilter        = NULL;
00022   m_CHOICEsliceFilter          = NULL;
00023   m_CHOICEsliceFilterKind      = NULL;
00024   m_CHOICEsliceFilterSize      = NULL;
00025   m_CHOICErenderMethod         = NULL;
00026   m_CHOICElowPass              = NULL;
00027   m_CHECKBOXinteractiveReconst = NULL;
00028   m_CHECKBOXchannels           = NULL;
00029   m_SLIDERimageScale           = NULL;
00030   m_BUTTONfitScale             = NULL;
00031   m_BUTTONpreprocess           = NULL;
00032   m_BUTTONreset                = NULL;
00033   m_BUTTONfill                 = NULL;
00034   m_BUTTONsave                 = NULL;
00035   m_SIZERpreprocess            = NULL;
00036   m_SIZERhint                  = NULL;
00037 
00038   m_FBRsubViewer               = NULL;
00039 }
00040 
00041 template <int S, class T>
00042 vuSimpleFBR<S,T>::~vuSimpleFBR()
00043 {
00044   CHECKNDELETE(m_Data);
00045   CHECKNDELETE(m_FourierFilter);
00046   CHECKNDELETE(m_SliceFilter);
00047   CHECKNDELETE(m_Image);
00048   CHECKNDELETE(m_FBRsubViewer);
00049   CHECKNDELETE(m_Interactive);
00050 
00051   m_CHOICEfilter               = NULL;
00052   m_TEXTfilterHint             = NULL;
00053   m_CHOICEfourierFilter        = NULL;
00054   m_CHOICEsliceFilter          = NULL;
00055   m_CHOICEsliceFilterKind      = NULL;
00056   m_CHOICEsliceFilterSize      = NULL;
00057   m_CHOICElowPass              = NULL;
00058   m_CHOICErenderMethod         = NULL;
00059   m_CHECKBOXinteractiveReconst = NULL;
00060   m_CHECKBOXchannels           = NULL;
00061   m_SLIDERimageScale           = NULL;
00062   m_BUTTONfitScale             = NULL;
00063   m_BUTTONpreprocess           = NULL;
00064   m_BUTTONreset                = NULL;
00065   m_BUTTONfill                 = NULL;
00066   m_BUTTONsave                 = NULL;
00067   m_SIZERpreprocess            = NULL;
00068   m_SIZERhint                  = NULL;
00069 
00070   m_FBRsubViewer               = NULL;
00071 }
00072 
00073 template <int S, class T>
00074 const char *vuSimpleFBR<S,T>::_titleString()
00075 {
00076   return "Simple Fourier Based Renderer";
00077 }
00078 
00079 
00080 template <int S, class T>
00081 bool vuSimpleFBR<S,T>::init(const char* DataFile)
00082 {
00083   SetEvtHandlerEnabled(true);
00084 
00085   //Set up the window
00086   SetTitle(_titleString());
00087   CreateStatusBar();
00088 
00089   // m_Data is instantiated in template instances
00090   m_Data->setFileName(DataFile);
00091 
00092   //Create Interactive Helper
00093   m_Interactive = new vuSphericInteractive<S,T>;
00094 
00095   //Create FBR subView
00096   m_FBRsubViewer = new vuFBRSubViewer<S,T>(this);
00097   m_FBRsubViewer->init(false);
00098   m_FBRsubViewer->setInteractive(m_Interactive);
00099   
00100   //Read in the data.
00101   bool success = m_Data->read();
00102   if (success) {
00103     m_glCanvas->SetSize(720,512);
00104     vuString str;
00105     str  = _titleString();
00106     str += ": [";
00107     str += m_Data->getWidth();
00108     str += "x";
00109     str += m_Data->getHeight();
00110     str += "] x ";
00111     str += m_Data->getNumberOfViews();
00112     str += " Views <";
00113     str += S;
00114     str += " ";
00115     str += m_Data->_typeName();
00116     str += ">";
00117     SetTitle(str.c_str());
00118     Fit();
00119     m_Data->setViewFilter(vuSphericViewFilterFactory<S,T>::getFilter("Fourier"));
00120     m_Interactive->setVolume(m_Data);
00121   }
00122   else {
00123     wxMessageDialog dlg(this,m_Data->getErrorMessage(), "vuSimpleFBR",wxOK);
00124     dlg.ShowModal();
00125   }
00126   return success;
00127 }
00128 
00129 
00130 /* ------------------------------------------------------------------------ */
00131 /* --- add some ui elements ----------------------------------------------- */
00132 /* ------------------------------------------------------------------------ */
00133 
00134 
00135 template <int S, class T>
00136 void vuSimpleFBR<S,T>::addRight(wxSizer *sizer)
00137 {
00138   wxBoxSizer *verSpacer = new wxBoxSizer(wxVERTICAL);
00139   wxBoxSizer *horSpacer = new wxBoxSizer(wxHORIZONTAL);
00140 
00141   // --- preprocessing interface -------------------------------------------
00142 
00143   wxStaticBox *myBox = new wxStaticBox(this, -1, "Preprocessing",
00144                                        wxDefaultPosition,
00145                                        wxSize(-1,-1),wxCAPTION);
00146   wxStaticBoxSizer *mySizer = new wxStaticBoxSizer(myBox, wxVERTICAL);
00147 
00148   // view filter
00149   {  
00150     m_CHOICEfilter = 
00151       new wxChoice(this, idFILTER, wxDefaultPosition, wxSize(96,20),
00152                    0, NULL, wxCAPTION, wxDefaultValidator, "Filter");
00153 
00154     m_CHOICEfilter->Append("Z-Axis");
00155     m_CHOICEfilter->Append("XZ-Axis");
00156     m_CHOICEfilter->Append("XYZ-Axis");
00157     m_CHOICEfilter->Append("Nearest");
00158     m_CHOICEfilter->Append("Fit Angle");
00159     m_CHOICEfilter->Append("All");
00160     m_CHOICEfilter->SetSelection(0);
00161   }
00162 
00163   // view filter hint
00164   {
00165     m_TEXTfilterHint = new wxTextCtrl(this,idFILTERHINT, "1",
00166                                       wxDefaultPosition,
00167                                       wxSize(30,18),
00168                                       wxTE_PROCESS_ENTER|wxTE_PROCESS_TAB|
00169                                       wxALIGN_RIGHT,
00170                                       wxTextValidator(wxFILTER_NUMERIC));
00171   }
00172     
00173   // reconstruction filter
00174   {
00175     m_CHOICEsliceFilter = 
00176       new wxChoice(this, idSLICEFILTER, wxDefaultPosition, wxSize(130,20),
00177                    0, NULL, wxCAPTION, wxDefaultValidator, "SliceFilter");
00178 
00179     dword    count        = 0;
00180     vuString *filterNames = NULL;
00181     
00182     vuSliceFilter::getFilterNames(filterNames, count);
00183     for (dword i=0; i< count; i++) {
00184       m_CHOICEsliceFilter->Append(filterNames[i].c_str());
00185     }
00186     m_CHOICEsliceFilter->SetSelection(0);
00187   }
00188 
00189   // reconstruction filter
00190   {
00191     m_CHOICEsliceFilterKind = 
00192       new wxChoice(this, idSLICEFILTERKIND, wxDefaultPosition, wxSize(130,20),
00193                    0, NULL, wxCAPTION, wxDefaultValidator, "SliceFilterKind");
00194 
00195     m_CHOICEsliceFilterKind->Append("separable");
00196     m_CHOICEsliceFilterKind->Append("spheric");
00197     m_CHOICEsliceFilterKind->SetSelection(0);
00198   }
00199 
00200 
00201   // filter size of reconstruction filter
00202   {
00203     m_CHOICEsliceFilterSize = 
00204       new wxChoice(this, idSLICEFILTERSIZE, wxDefaultPosition, wxSize(130,20),
00205                    0, NULL, wxCAPTION, wxDefaultValidator, "SliceFilterSize");
00206 
00207     for (dword i=1; i <= MAX_SLICE_FILTER_SIZE; i++) {
00208       m_CHOICEsliceFilterSize->Append(vuString(i).c_str());
00209     }
00210     m_CHOICEsliceFilterSize->SetSelection(0);
00211   }
00212 
00213   // lowPass factor
00214 
00215   {
00216     m_CHOICElowPass = 
00217       new wxChoice(this, idLOWPASS, wxDefaultPosition, wxSize(130,20),
00218                    0, NULL, wxCAPTION, wxDefaultValidator, "LowPassFactor");
00219     m_CHOICElowPass->Append("100 %");
00220     m_CHOICElowPass->Append(" 75 %");
00221     m_CHOICElowPass->Append(" 50 %");
00222     m_CHOICElowPass->Append(" 25 %");
00223     m_CHOICElowPass->Append(" 15 %");
00224     m_CHOICElowPass->Append(" 10 %");
00225     m_CHOICElowPass->Append("  5 %");
00226     m_CHOICElowPass->Append("  2 %");
00227     m_CHOICElowPass->Append("  1 %");
00228     m_CHOICElowPass->SetSelection(0);
00229   }
00230   
00231   // interactive reconstruction checkbox
00232   {
00233     m_CHECKBOXinteractiveReconst =
00234       new wxCheckBox(this, idINTERACT_RECONST, "", wxDefaultPosition,
00235                      wxSize(15,15));
00236   }
00237   
00238   wxFlexGridSizer *tmp;
00239 
00240   tmp = new wxFlexGridSizer(2,5,5);
00241   tmp->Add(80,5);
00242   tmp->Add(0,5);
00243   tmp->Add(new wxStaticText(this, -1, "Views:"), 0, wxALIGN_RIGHT);
00244   
00245   {
00246     m_SIZERhint = new wxBoxSizer(wxHORIZONTAL);
00247     
00248     tmp->Add(m_SIZERhint);
00249 
00250     _filterHintTextUpdate();
00251   }
00252   
00253 
00254   tmp->Add(new wxStaticText(this, -1, "Filter:"), 0, wxALIGN_RIGHT);
00255   tmp->Add(m_CHOICEsliceFilter,0,wxALL|wxALIGN_LEFT,1);
00256   tmp->Add(new wxStaticText(this, -1, "Filter Type:"), 0, wxALIGN_RIGHT);
00257   tmp->Add(m_CHOICEsliceFilterKind,0,wxALL|wxALIGN_LEFT,1);
00258   tmp->Add(new wxStaticText(this, -1, "Filter Size:"), 0, wxALIGN_RIGHT);
00259   tmp->Add(m_CHOICEsliceFilterSize,0,wxALL|wxALIGN_LEFT,1);
00260   tmp->Add(new wxStaticText(this, -1, "Low Pass:"), 0, wxALIGN_RIGHT);
00261   tmp->Add(m_CHOICElowPass,0,wxALL|wxALIGN_LEFT,1);
00262 
00263   tmp->Add(new wxStaticText(this, -1, "Interactive:"), 0, wxALIGN_RIGHT);
00264   tmp->Add(m_CHECKBOXinteractiveReconst);
00265 
00266   tmp->Add(80,5);
00267   tmp->Add(0, 5);
00268 
00269   m_BUTTONpreprocess = new wxButton(this, idPREPROCESS,
00270                                     "        Preprocess        ");
00271   m_BUTTONreset      = new wxButton(this, idRESET, "   Start  ");
00272   m_BUTTONfill       = new wxButton(this, idFILL,  "   Fill   ");
00273 
00274   m_BUTTONreset->Show(false);
00275   m_BUTTONfill->Show(false);
00276 
00277   mySizer->Add(tmp);
00278   {
00279     m_SIZERpreprocess = new wxBoxSizer(wxHORIZONTAL);
00280 
00281     m_SIZERpreprocess->Add(m_BUTTONpreprocess);
00282     m_SIZERpreprocess->Layout();
00283     m_SIZERpreprocess->Fit(this);
00284 
00285     mySizer->Add(m_SIZERpreprocess , 0, wxALIGN_CENTER);
00286   }
00287   mySizer->Add(0,5);
00288 
00289   verSpacer->Add(mySizer,0,wxEXPAND, 5);
00290 
00291 
00292   // --- rendering interface ------------------------------------------------
00293 
00294   myBox   = new wxStaticBox(this, -1, "Rendering", wxDefaultPosition,
00295                             wxSize(-1,-1),wxCAPTION);
00296   mySizer = new wxStaticBoxSizer(myBox, wxVERTICAL);
00297 
00298   tmp = new wxFlexGridSizer(2,5,5);
00299 
00300   // interpolation filter for slicing
00301   {
00302     dword    count        = 0;
00303     vuString *filterNames = NULL;
00304     
00305     m_CHOICEfourierFilter = 
00306       new wxChoice(this, idFOURIERFILTER, wxDefaultPosition, wxSize(130,20),
00307                    0, NULL, wxCAPTION, wxDefaultValidator, "SliceFilter");
00308 
00309     vuTorstensFourierFilter::getFilterNames(filterNames, count);
00310     for (dword i=0; i< count; i++) {
00311       if (filterNames[i].hasPrefix("d0"))
00312         m_CHOICEfourierFilter->Append(filterNames[i].c_str());
00313     }
00314     m_CHOICEfourierFilter->SetSelection(0);
00315   }
00316 
00317   // render method choice
00318   {
00319     m_CHOICErenderMethod =
00320       new wxChoice(this, idRENDERMETHOD, wxDefaultPosition, wxSize(130,20),
00321                    0, NULL, wxCAPTION, wxDefaultValidator, "RenderMethod");
00322 
00323     m_CHOICErenderMethod->Append("Spatial");
00324     m_CHOICErenderMethod->Append("Freq. Amplitude ");
00325     m_CHOICErenderMethod->Append("Freq. Phase");
00326     m_CHOICErenderMethod->Append("Freq. Real");
00327     m_CHOICErenderMethod->Append("Freq. Imaginary");
00328 
00329     m_CHOICErenderMethod->SetSelection(0);
00330   }
00331 
00332   // image scale factor
00333   {
00334     m_SLIDERimageScale =
00335       new wxSlider(this, idIMAGESCALE, 1, 1, 10000, wxDefaultPosition,
00336                    wxSize(106,16), wxSL_HORIZONTAL, 
00337                    wxDefaultValidator, "imageScaleSlider");
00338     m_SLIDERimageScale->SetValue(2550);
00339   }
00340 
00341   // image scale fit button
00342   {
00343     m_BUTTONfitScale = new wxButton(this,idFITSCALE,"fit",
00344                                     wxPoint(0,0),wxSize(20,16));
00345   }
00346   wxBoxSizer *scaleSizer = new wxBoxSizer(wxHORIZONTAL);
00347   scaleSizer->Add(m_SLIDERimageScale);
00348   scaleSizer->Add(2,0);
00349   scaleSizer->Add(m_BUTTONfitScale);
00350   
00351   tmp->Add(80,5);
00352   tmp->Add(0, 5);
00353   tmp->Add(new wxStaticText(this, -1, "Filter:"), 0, wxALIGN_RIGHT);
00354   tmp->Add(m_CHOICEfourierFilter,0,wxALL|wxALIGN_LEFT,1);
00355 
00356   tmp->Add(new wxStaticText(this, -1, "Method:"), 0, wxALIGN_RIGHT);
00357   tmp->Add(m_CHOICErenderMethod,0,wxALL|wxALIGN_LEFT,1);
00358 
00359   _addChannelControls(tmp); // add r g b checkboxes (only for 3B)
00360 
00361   tmp->Add(new wxStaticText(this,-1,"Scale:"),0,wxALIGN_RIGHT|wxALIGN_BOTTOM);
00362   tmp->Add(scaleSizer,0,wxALL|wxALIGN_LEFT,1);
00363 
00364   tmp->Add(new wxStaticText(this, -1, "Snap To View:"), 0, wxALIGN_RIGHT);
00365   tmp->Add(new wxButton(this,idSNAP2VIEW,"snap", wxDefaultPosition,
00366                         wxSize(130,18)), 0, wxALL|wxALIGN_LEFT,1);
00367 
00368   tmp->Add(new wxStaticText(this, -1, "Sub Window:"), 0, wxALIGN_RIGHT);
00369   tmp->Add(new wxButton(this,idSHOWSUBWINDOW,"show", wxDefaultPosition,
00370                         wxSize(130,18)), 0, wxALL|wxALIGN_LEFT,1);
00371   
00372   tmp->Add(0,3);
00373   tmp->Add(0,3);
00374 
00375   mySizer->Add(tmp);
00376 
00377   verSpacer->Add(0,15);
00378   verSpacer->Add(mySizer);
00379 
00380   // --- misc  -------------------------------------------
00381 
00382   myBox   = new wxStaticBox(this, -1, "Misc",wxDefaultPosition,
00383                             wxSize(-1,-1),wxCAPTION);
00384   mySizer = new wxStaticBoxSizer(myBox, wxVERTICAL);
00385 
00386   tmp = new wxFlexGridSizer(2,5,5);
00387 
00388   m_BUTTONsave = new wxButton(this, idSAVE, "save",
00389                               wxDefaultPosition,wxSize(130,20));
00390 
00391   tmp->Add(80,1);
00392   tmp->Add(0, 1);
00393 
00394   tmp->Add(new wxStaticText(this, -1, "Save:"), 0, wxALIGN_RIGHT);
00395   tmp->Add(m_BUTTONsave);
00396 
00397   tmp->Add(0,3);
00398   tmp->Add(0,3);
00399 
00400   mySizer->Add(tmp);
00401 
00402   verSpacer->Add(0,15);
00403   verSpacer->Add(mySizer);
00404 
00405   // ------------------------------------------------------------------------
00406   
00407   horSpacer->Add(10,0);
00408   horSpacer->Add(verSpacer);
00409   horSpacer->Add(10,0);
00410 
00411   sizer->Add(horSpacer,0,wxEXPAND, 5);
00412 }
00413 
00414 
00415 template <int S, class T>
00416 bool vuSimpleFBR<S,T>::glInit()
00417 {
00418   if (m_Data == NULL) return false;
00419   m_Data->initOpenGL();
00420   m_Data->glResize(m_glCanvas->getWidth(), m_glCanvas->getHeight());
00421   return true;
00422 }
00423 
00424 template <int S, class T>
00425 void vuSimpleFBR<S,T>::glRender()
00426 {
00427   _interactiveReconstruction(); // reconstruct interactively (if enabled)
00428 
00429   _renderImage();  // render image and store the result in m_Image
00430 
00431   _displayImage(); // display m_Image
00432 
00433   m_FBRsubViewer->redraw();
00434 }
00435 
00436 
00437 template <int S, class T>
00438 void vuSimpleFBR<S,T>::glResize()
00439 {
00440   m_Data->glResize(m_glCanvas->getWidth(), m_glCanvas->getHeight());
00441 }
00442 
00443 template <int S, class T>
00444 void vuSimpleFBR<S,T>::onMouse(wxMouseEvent &ev)
00445 {
00446   // here is the place for additional mouse bevaviour.
00447 }
00448 
00449 template <int S, class T>
00450 void vuSimpleFBR<S,T>::onKeyboard(wxKeyEvent& event)
00451 {
00452 }
00453 
00454 template <int S, class T>
00455 vu1 *vuSimpleFBR<S,T>::getVolume()
00456 {
00457   return (vu1 *)m_Data;
00458 }
00459 
00460 /* --------------------------------------------------------------------- */
00461 /* --- some GUI callbacks ---------------------------------------------- */
00462 /* --------------------------------------------------------------------- */
00463 
00464 template <int S, class T>
00465 void vuSimpleFBR<S,T>::OnButtonPreprocess(wxCommandEvent& event)
00466 {
00467   bool isPreprocess = false;
00468 
00469   _updateFourierFilter();
00470   isPreprocess = _updateSliceFilter();
00471   isPreprocess = _updateViewFilter(isPreprocess);
00472 
00473   if (isPreprocess) {
00474     vuSimpleProgressHandler handler(this);
00475     m_Data->preprocess(&handler);
00476   }
00477   else
00478     cout << "No preprocessing neccessary!" << endl;
00479 
00480   m_Data->setIsReRendering(true);
00481   m_glCanvas->redraw();
00482 }
00483 
00484 template <int S, class T>
00485 void vuSimpleFBR<S,T>::OnButtonReset(wxCommandEvent& event)
00486 {
00487   if (m_BUTTONreset->GetLabel() == "Start")
00488     m_BUTTONreset->SetLabel("Reset");
00489 
00490   _resetInteractivePreprocessing();
00491   m_Data->setIsReRendering(true);
00492   m_glCanvas->redraw();
00493 }
00494 
00495 template <int S, class T>
00496 void vuSimpleFBR<S,T>::OnButtonFill(wxCommandEvent& event)
00497 {
00498   vuSphericViewFilter<S,T> *filter = m_Data->getViewFilter();
00499   int   idx;
00500   dword cnt = filter->getNumberOfViews();
00501   
00502   for (dword i=0; i<cnt; i++) {
00503     idx = m_Data->getIndexOfView(filter->getView(i));
00504     if (idx <0) continue;
00505     if (!m_Interactive->isVisited(idx)) {
00506       m_Interactive->setIsVisited(idx, true);
00507       _addViewWithIndex(idx); //, i);
00508     }
00509   }
00510   m_Data->setIsReRendering(true);
00511   m_glCanvas->redraw();
00512 }
00513 
00514 template <int S, class T>
00515 void vuSimpleFBR<S,T>::OnChoiceRenderMethod(wxCommandEvent& event)
00516 {
00517   if (m_CHOICErenderMethod->GetSelection() == 0) { // spatial domain
00518     m_SLIDERimageScale->SetValue(255*10);
00519   }
00520   else { // frequency domain
00521     m_SLIDERimageScale->SetValue(1);
00522   }
00523   m_Data->setIsReRendering(true);
00524   m_glCanvas->redraw();
00525 }
00526 
00527 template <int S, class T>
00528 void vuSimpleFBR<S,T>::OnChoiceFilter(wxCommandEvent& event)
00529 {
00530   _filterHintTextUpdate();
00531 }
00532 
00533 template <int S, class T>
00534 void vuSimpleFBR<S,T>::OnChoiceFourierFilter(wxCommandEvent& event)
00535 {
00536   vuTorstensFourierFilter *tmp = m_FourierFilter;
00537   vuString name = m_CHOICEfourierFilter->GetStringSelection().c_str();
00538 
00539   if (m_FourierFilter) {
00540     if (m_FourierFilter->getFilterName() == name) return;
00541   }
00542 
00543   m_FourierFilter = vuTorstensFourierFilter::getFilter(name);
00544 
00545   if (m_FourierFilter) {
00546     getFourierViewFilter()->setFourierFilter(m_FourierFilter);
00547     CHECKNDELETE(tmp);
00548   }
00549   else
00550     m_FourierFilter = tmp;
00551 
00552   m_Data->setIsReRendering(true);
00553   m_glCanvas->redraw();  
00554 }
00555 
00556 template <int S, class T>
00557 void vuSimpleFBR<S,T>::OnButtonSnap2View(wxCommandEvent& event)
00558 {
00559   vuSphericViewFilter<S,T> *subFilter = m_Data->getViewFilter();
00560   dword                    numOfViews = subFilter->getNumberOfViews();
00561 
00562   if (numOfViews > 0) {
00563     vuSphericView<S,T>** views = subFilter->getViews();
00564     vuCamera          *camera  = m_Data->getCameraPtr();
00565     dword             *idxList = NULL;
00566     dword             count    = 1;
00567     vuVector          lookAt   = camera->getLookAtVector();
00568     vuVector          up       = camera->getUpVector();
00569     vuVector          right    = camera->getRightVector();
00570 
00571     lookAt.makeUnit();
00572     vuSphericFilter<S,T>::getNearestViews(idxList, count, lookAt * -1,
00573                                           numOfViews, views);    
00574 
00575     if (count != 1) return;
00576 
00577     vuVector lookFrom = views[idxList[0]]->getLookFrom();
00578 
00579     // check opposite view direction as well...
00580     {
00581       CHECKNDELETE(idxList);
00582       vuVector looookAt = lookAt * -1;
00583       
00584       looookAt.makeUnit();
00585       vuSphericFilter<S,T>::getNearestViews(idxList, count, looookAt * -1,
00586                                             numOfViews, views);
00587 
00588       if (count != 1) return;
00589 
00590       vuVector looookFrom = views[idxList[0]]->getLookFrom();
00591       looookFrom.makeUnit();
00592 
00593       if (fabs(looookFrom.dot(looookAt)) > fabs(lookFrom.dot(lookAt))) {
00594         lookFrom = looookFrom;
00595       }
00596     }
00597     bool isFromBack;
00598     
00599     if (lookAt.dot(lookFrom) < 0) {
00600       isFromBack = true;
00601       lookAt = lookFrom * -1;
00602     }
00603     else {
00604       isFromBack = false;
00605       lookAt = lookFrom;
00606     }
00607     
00608     vuFourierVolume<S>::calcViewVectors(lookAt, up, right);
00609     
00610     camera->setLookAtVector(lookAt);
00611     camera->setUpVector(up);
00612     camera->setRightVector(right);
00613     camera->init();
00614 
00615     CHECKNDELETE(idxList);
00616   }
00617   m_Data->setIsReRendering(true);
00618   m_glCanvas->redraw();
00619 }
00620 
00621 template <int S, class T>
00622 void vuSimpleFBR<S,T>::OnButtonFitScale(wxCommandEvent& event)
00623 {
00624   if (m_Image == NULL) return;
00625 
00626   float minValue =  100000000000.0f;
00627   float maxValue = -100000000000.0f;
00628 
00629   for (int i=0; i<S; i++) {
00630     float minVal, maxVal;
00631 
00632     m_Image->getMinAndMaxValue(minVal, maxVal, i);
00633 
00634     if (minValue > minVal) minValue = minVal;
00635     if (maxValue < maxVal) maxValue = maxVal;
00636   }
00637 
00638   m_SLIDERimageScale->SetValue((int)(maxValue*10));
00639 
00640   m_glCanvas->redraw();
00641 }
00642 
00643 template <int S, class T>
00644 void vuSimpleFBR<S,T>::OnButtonShowSubWindow(wxCommandEvent& event)
00645 {
00646   _updateFourierFilter();
00647   m_FBRsubViewer->Show(true);
00648 }
00649 
00650 template <int S, class T>
00651 void vuSimpleFBR<S,T>::OnButtonSave(wxCommandEvent& event)
00652 {
00653   wxFileDialog *saveDialog = NULL;
00654 
00655   saveDialog = new wxFileDialog(this, "Save Reconstructed Volume",
00656                                 "", // default dir
00657                                 "", // default file
00658                                 "Fourier Volume (*.fvr)| *.fvr|"
00659                                 "Spatial Volume (*.vud)| *.vud", //wildcard
00660                                 wxHIDE_READONLY|wxSAVE|wxOVERWRITE_PROMPT);
00661   if (saveDialog->ShowModal() == wxID_OK) { // OK pressed
00662     if (saveDialog->GetFilterIndex() == 0) { // save fourier volume (*.fvr)
00663       const char *fileName = saveDialog->GetPath();
00664       CHECKNDELETE(saveDialog);
00665       m_glCanvas->redraw();
00666       Refresh();
00667 
00668       vuSimpleProgressHandler handle(this, "Writing Frequency Volume To Disk");
00669       getFourierViewFilter()->writeFourierToFile(fileName, &handle);
00670     }
00671     else { // save spatial volume (*.vud)
00672       getFourierViewFilter()->writeSpatialVolume(saveDialog->GetPath());
00673       CHECKNDELETE(saveDialog);
00674     }
00675   }
00676 }
00677 
00678 template <int S, class T>
00679 void vuSimpleFBR<S,T>::OnCheckboxInteractiveReconst(wxCommandEvent& event)
00680 {
00681   if (m_CHECKBOXinteractiveReconst->GetValue()) {
00682     m_SIZERpreprocess->Remove(0);
00683     m_SIZERpreprocess->Add(m_BUTTONfill);
00684     m_SIZERpreprocess->Add(m_BUTTONreset);
00685     m_BUTTONpreprocess->Show(false);
00686     m_BUTTONreset->Show(true);
00687     m_BUTTONfill->Show(true);
00688     m_BUTTONreset->SetLabel("Start");
00689     m_SIZERpreprocess->Layout();
00690     m_SIZERpreprocess->Fit(this);
00691   }
00692   else {
00693     getFourierViewFilter()->setNoInteractiveMode();
00694     m_SIZERpreprocess->Remove(1);
00695     m_SIZERpreprocess->Remove(0);
00696     m_SIZERpreprocess->Add(m_BUTTONpreprocess);
00697     m_BUTTONpreprocess->Show(true);
00698     m_BUTTONreset->Show(false);
00699     m_BUTTONfill->Show(false);
00700     m_SIZERpreprocess->Layout();
00701     m_SIZERpreprocess->Fit(this);
00702   }
00703   m_glCanvas->redraw();
00704 }
00705 
00706 template <int S, class T>
00707 void vuSimpleFBR<S,T>::OnCheckboxChannels(wxCommandEvent& event)
00708 {
00709   m_glCanvas->redraw();
00710 }
00711 
00712 template <int S, class T>
00713 void vuSimpleFBR<S,T>::OnSliderImageScale(wxScrollEvent& event)
00714 {
00715   m_glCanvas->redraw();
00716 }
00717 
00718 
00719 template <int S, class T>
00720 vuCamera* vuSimpleFBR<S,T>::getCamera()
00721 {
00722   return m_Data->getCameraPtr ();
00723 }
00724 
00725 template <int S, class T>
00726 vuImage* vuSimpleFBR<S,T>::getCurrentImage()
00727 {
00728   return NULL;
00729 }
00730 
00731 
00732 template <int S, class T>
00733 void vuSimpleFBR<S,T>::DrawFromImage()
00734 {
00735   m_glCanvas->redraw ();
00736 }
00737 
00738 template <int S, class T>
00739 void vuSimpleFBR<S,T>::DrawAgain()
00740 {
00741 }
00742 
00743 /* --------------------------------------------------------------------- */
00744 /* --- some private functions ------------------------------------------ */
00745 /* --------------------------------------------------------------------- */
00746 
00747 template <int S, class T>
00748 vuSphVwFlt_Fourier<S,T> *vuSimpleFBR<S,T>::getFourierViewFilter()
00749 {
00750   return (vuSphVwFlt_Fourier<S,T> *)(m_Data->getViewFilter());
00751 }
00752 
00753 template <int S, class T>
00754 bool vuSimpleFBR<S,T>::_updateViewFilter(bool isPreprocess)
00755 {
00756   vuString             name    = m_CHOICEfilter->GetStringSelection().c_str();
00757   vuSphericFilter<S,T> *filter = m_Data->getFilter();
00758   bool                 isNew   = false;
00759 
00760   if (filter->getFilterName() != name) {
00761     filter = vuSphericFilterFactory<S,T>::getFilter(name);
00762     isNew  = true;
00763   }
00764 
00765   if (name == "Nearest") {
00766     vuSphLfFlt_Nearest<S,T> *flt = (vuSphLfFlt_Nearest<S,T> *)filter;
00767     unsigned long num;
00768 
00769     m_TEXTfilterHint->GetValue().ToULong(&num);
00770     if (num < 1) num = 1;
00771     if (num > m_Data->getNumberOfViews()) num = m_Data->getNumberOfViews();
00772 
00773     if (num != flt->getNumberOfViews()) {
00774       flt->setNumberOfViews(num);
00775       isPreprocess = true;
00776     }
00777     m_TEXTfilterHint->SetValue(vuString(num).c_str());
00778   }
00779   else if (name == "Fit Angle") {
00780     vuSphLfFlt_FitAngle<S,T> *flt = (vuSphLfFlt_FitAngle<S,T> *)filter;
00781     double angle;
00782 
00783     m_TEXTfilterHint->GetValue().ToDouble(&angle);
00784     flt->setAngle(angle);
00785     m_TEXTfilterHint->SetValue(vuString((dword)flt->getAngle()).c_str());
00786     isPreprocess = true;
00787   }
00788   
00789   vuSphVwFlt_Fourier<S,T> *fbr = getFourierViewFilter();
00790 
00791   fbr->setFourierFilter(m_FourierFilter);
00792 
00793   if (isNew) {
00794     fbr->setSliceFilter(m_SliceFilter);
00795     m_Data->setFilter(filter);
00796     m_Data->glResize(m_glCanvas->getWidth(), m_glCanvas->getHeight());
00797   }
00798   else if (isPreprocess) {
00799     fbr->setSliceFilter(m_SliceFilter);
00800   }
00801   return (isNew || isPreprocess);
00802 }
00803 
00804 template <int S, class T>
00805 void vuSimpleFBR<S,T>::_updateFourierFilter()
00806 {
00807   vuTorstensFourierFilter *tmp = m_FourierFilter;
00808   vuString name = m_CHOICEfourierFilter->GetStringSelection().c_str();
00809 
00810   if (m_FourierFilter) {
00811     if (m_FourierFilter->getFilterName() == name) return;
00812   }
00813 
00814   m_FourierFilter = vuTorstensFourierFilter::getFilter(name);
00815 
00816   CHECKNDELETE(tmp);
00817 }
00818 
00819 template <int S, class T>
00820 bool vuSimpleFBR<S,T>::_updateSliceFilter()
00821 {
00822   vuSliceFilter *tmp = m_SliceFilter;
00823   vuString      name = m_CHOICEsliceFilter->GetStringSelection().c_str();
00824   bool     isUpdated = (m_SliceFilter == NULL);
00825   float   oldLowPass = (tmp == NULL) ? 1.0 : tmp->getLowPassFactor();
00826 
00827   if (m_SliceFilter) {
00828     isUpdated = (m_SliceFilter->getFilterName() != name);
00829   }
00830 
00831   if (isUpdated) {
00832     m_SliceFilter = vuSliceFilter::getFilter(name.c_str());
00833     CHECKNDELETE(tmp);
00834   }
00835   
00836   // update lowPass factor
00837   {
00838     double newLowPass;
00839 
00840     if (m_CHOICElowPass->GetSelection() == 0)
00841       newLowPass = 1.0;
00842     else {
00843       wxString str = m_CHOICElowPass->GetStringSelection().BeforeLast('%');
00844       str.ToDouble(&newLowPass);
00845       newLowPass /= 100;
00846     }
00847 
00848     if (fabs(oldLowPass - newLowPass) > 0.0001) {
00849       isUpdated = true;
00850       m_SliceFilter->setLowPassFactor(newLowPass);
00851     }
00852   }
00853   
00854   // update filter width
00855   {  
00856     dword size = m_CHOICEsliceFilterSize->GetSelection() + 1;
00857 
00858     if (m_SliceFilter->getWidth() != size) {
00859       m_SliceFilter->setWidth(size);
00860       isUpdated = true;
00861     }
00862   }
00863   
00864   // update filter type
00865   {
00866     byte kind = m_CHOICEsliceFilterKind->GetSelection();
00867 
00868     if (m_SliceFilter->getKind() != kind) {
00869       m_SliceFilter->setKind(kind);
00870       isUpdated = true;
00871     }
00872   }
00873 
00874   return isUpdated;
00875 }
00876 
00877 template <int S, class T>
00878 void vuSimpleFBR<S,T>::_filterHintTextUpdate()
00879 {
00880   vuString name = m_CHOICEfilter->GetStringSelection().c_str();
00881 
00882   m_SIZERhint->Remove(0);
00883   m_SIZERhint->Remove(0);
00884 
00885   if (name == "Fit Angle") { 
00886     m_CHOICEfilter->SetSize(96,20);
00887     m_SIZERhint->Add(m_CHOICEfilter,   0, wxALL|wxALIGN_LEFT,1);
00888     m_SIZERhint->Add(m_TEXTfilterHint, 0, wxALL|wxALIGN_LEFT,1);
00889     m_TEXTfilterHint->Show(true);
00890     m_TEXTfilterHint->SetValue("45");
00891     m_TEXTfilterHint->SetInsertionPointEnd();
00892   }
00893   else if (name == "Nearest") {
00894     m_CHOICEfilter->SetSize(96,20);
00895     m_SIZERhint->Add(m_CHOICEfilter,   0, wxALL|wxALIGN_LEFT,1);
00896     m_SIZERhint->Add(m_TEXTfilterHint, 0, wxALL|wxALIGN_LEFT,1);
00897     m_TEXTfilterHint->Show(true);
00898     m_TEXTfilterHint->SetValue("1");
00899     m_TEXTfilterHint->SetInsertionPointEnd();
00900   }
00901   else {
00902     m_CHOICEfilter->SetSize(130,20);
00903     m_SIZERhint->Add(m_CHOICEfilter, 0, wxALL|wxALIGN_LEFT,1);
00904     m_TEXTfilterHint->Show(false);    
00905   }
00906   m_SIZERhint->Layout();
00907   m_SIZERhint->Fit(this);
00908 }
00909 
00910 template <int S, class T>
00911 void vuSimpleFBR<S,T>::_resetInteractivePreprocessing()
00912 {
00913   bool isPreprocess = false;
00914 
00915   _updateFourierFilter();
00916   isPreprocess = _updateSliceFilter();
00917   isPreprocess = _updateViewFilter(isPreprocess);
00918 
00919   vuSphVwFlt_Fourier<S,T> *filter = getFourierViewFilter();
00920   cerr << "prepare for interactive reconstruction..." << endl;
00921   filter->prepareForInteractive(m_Data->getWidth(), m_Data->getHeight());
00922   m_Data->getFilter()->applyFilteredViews(m_Data->getViewFilter());
00923   m_Interactive->reset();
00924 }
00925 
00926 template <int S, class T>
00927 void vuSimpleFBR<S,T>::_addViewWithIndex(dword idx) //, int idxInFilter)
00928 {
00929   wxStopWatch watch;
00930   // vuFourierCluster<T> *cluster = getFourierCluster(); // ???
00931 
00932   watch.Start();
00933   // cluster->addView(m_Data->getView(idx));
00934   watch.Pause();
00935 
00936   cerr << "add view: ";
00937   cerr.width(3);
00938   cerr << idx;
00939   cerr << "   (";
00940   cerr.width(3);
00941   cerr << m_Interactive->getNumberOfVisited();
00942   cerr << " of ";
00943   cerr << m_Data->getViewFilter()->getNumberOfViews();
00944   cerr << ")   [";
00945   cerr << watch.Time();
00946   cerr << " ms]" << endl;
00947 }
00948 
00949 template <int S, class T>
00950 void vuSimpleFBR<S,T>::_addChannelControls(wxFlexGridSizer *sizer)
00951 {
00952   vuString str;
00953 
00954   if (S == 1)
00955     return;
00956   else if (S == 2)
00957     str = "IA";
00958   else if (S == 3)
00959     str = "RGB";
00960   else
00961     return;
00962 
00963   wxBoxSizer *channelSpacer = new wxBoxSizer(wxHORIZONTAL);
00964 
00965   m_CHECKBOXchannels = new wxCheckBox*[S];
00966 
00967   for (int i=0; i<S; i++) {
00968     m_CHECKBOXchannels[i] = new wxCheckBox(this, idCHANNELS, str[(dword)i],
00969                                           wxDefaultPosition, wxSize(130/S,15));
00970     m_CHECKBOXchannels[i]->SetValue(true);
00971     channelSpacer->Add(m_CHECKBOXchannels[i]);
00972   }
00973 
00974   sizer->Add(new wxStaticText(this, -1, "Channels:"), 0, wxALIGN_RIGHT);
00975   sizer->Add(channelSpacer,0,wxALL|wxALIGN_LEFT,1);
00976 }
00977 
00978 
00979 template <int S, class T>
00980 void vuSimpleFBR<S,T>::_interactiveReconstruction()
00981 {
00982   vuSphVwFlt_Fourier<S,T> *filter = getFourierViewFilter();
00983 
00984   // do interactive preprocessing if it's asked for
00985   if (filter->isPreparedForInteractive()) {
00986     int  idx   = m_Interactive->indexOfNearestView(); 
00987     bool isNew = !m_Interactive->isVisited(idx);
00988 
00989     if (isNew && idx >= 0) {
00990       m_Interactive->setIsVisited(idx,true);
00991       //filter->setFilter(m_FourierFilter);
00992       //filter->setSliceFilter(m_SliceFilter);
00993       //_addViewWithIndex(idx);
00994     }
00995   }
00996 }
00997 
00998 template <int S, class T>
00999 void vuSimpleFBR<S,T>::_renderImage()
01000 {
01001   if (m_Data->IsReRendering()) {
01002     int method = m_CHOICErenderMethod->GetSelection();
01003 
01004     if (method < 0) return;
01005 
01006     wxStopWatch watch;
01007 
01008     watch.Start();
01009 
01010     vuCamera *camera = m_Data->getCameraPtr();
01011 
01012     getFourierViewFilter()->computeUnscaledImage(camera, m_Image, method);
01013     m_Image->glResize(m_glCanvas->getWidth(), m_glCanvas->getHeight());
01014     m_Data->setIsReRendering(false);
01015 
01016     watch.Pause();
01017 
01018     // --- update status text ------------------
01019     wxString statusText = "Render Time: ";
01020     int      idx        = m_Interactive->indexOfNearestView();
01021     
01022     statusText += vuString(watch.Time()).c_str();
01023     statusText += "ms";
01024     if (idx >= 0) {  
01025       statusText += " [view=";
01026       statusText += vuString(idx).c_str();
01027       statusText += "]";
01028     }    
01029     SetStatusText(statusText);
01030 
01031     // redraw sub viewer
01032   }
01033 }
01034 
01035 template <int S, class T>
01036 void vuSimpleFBR<S,T>::_displayImage()
01037 {
01038   float scale = (float)m_SLIDERimageScale->GetValue() / 10;
01039 
01040   // chose the channels from m_Image and display them
01041   {
01042     vuFixelMap<S,float> *img = NULL;
01043 
01044     img = new vuFixelMap<S,float>(m_Image->getWidth(), m_Image->getHeight());
01045 
01046     bool status = true;
01047 
01048     if (m_CHECKBOXchannels != NULL) {
01049       for (int i=0;i<S;i++) status=status && m_CHECKBOXchannels[i]->GetValue();
01050     }
01051 
01052     if (status)
01053       *img = *m_Image;
01054     else {
01055       vuFixelMap<1,float> *imag = NULL;
01056 
01057       imag = new vuFixelMap<1,float>(m_Image->getWidth(),m_Image->getHeight());
01058 
01059       for (int i=0; i<S; i++) {
01060         if (m_CHECKBOXchannels[i]->GetValue()) {
01061           m_Image->getChannel(imag,i);
01062           img->copyMapToChannel(imag,i);
01063         }
01064       }
01065       CHECKNDELETE(imag);
01066     }
01067 
01068     *img /= scale;
01069     img->glRender();
01070     CHECKNDELETE(img);
01071   }
01072 }

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