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
00086 SetTitle(_titleString());
00087 CreateStatusBar();
00088
00089
00090 m_Data->setFileName(DataFile);
00091
00092
00093 m_Interactive = new vuSphericInteractive<S,T>;
00094
00095
00096 m_FBRsubViewer = new vuFBRSubViewer<S,T>(this);
00097 m_FBRsubViewer->init(false);
00098 m_FBRsubViewer->setInteractive(m_Interactive);
00099
00100
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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);
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
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();
00428
00429 _renderImage();
00430
00431 _displayImage();
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
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
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);
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) {
00518 m_SLIDERimageScale->SetValue(255*10);
00519 }
00520 else {
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
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 "",
00657 "",
00658 "Fourier Volume (*.fvr)| *.fvr|"
00659 "Spatial Volume (*.vud)| *.vud",
00660 wxHIDE_READONLY|wxSAVE|wxOVERWRITE_PROMPT);
00661 if (saveDialog->ShowModal() == wxID_OK) {
00662 if (saveDialog->GetFilterIndex() == 0) {
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 {
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
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
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
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
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)
00928 {
00929 wxStopWatch watch;
00930
00931
00932 watch.Start();
00933
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
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
00992
00993
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
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
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
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 }