|
NIREP
|
00001 /*========================================================================= 00002 00003 Program: vtkINRIA3D 00004 Module: $Id: wxVtkImageFlip.cxx,v 1.2 2009/08/03 18:57:39 hawle Exp $ 00005 Language: C++ 00006 Author: $Author: hawle $ 00007 Date: $Date: 2009/08/03 18:57:39 $ 00008 Version: $Revision: 1.2 $ 00009 00010 Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. 00011 See Copyright.txt for details. 00012 00013 This software is distributed WITHOUT ANY WARRANTY; without even 00014 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00015 PURPOSE. See the above copyright notices for more information. 00016 00017 =========================================================================*/ 00018 00019 00020 00021 00022 #include "wxVtkImageFlip.h" 00023 00024 #include "wxVTKRenderWindowInteractor.h" 00025 #include "NIREPvtkViewImage2D.h" 00026 #include "vtkImageData.h" 00027 #include <vtkImageFlip.h> 00028 #include <vtkRenderer.h> 00029 #include <vtkImageReslice.h> 00030 00031 #include "wxCommon.h" 00032 00033 wxVtkImageFlip::wxVtkImageFlip (wxWindow* parent, int id, 00034 const wxString& title, 00035 const wxPoint& pos, 00036 const wxSize& size, 00037 long style) 00038 : wxDialog(parent, id, title, pos, size, style) 00039 { 00040 00041 00042 this->AcquisitionTxt = new wxStaticText(this, -1, wxT("Acquisition Orientation:")); 00043 this->ComboAcquisition = new wxComboBox (this, COMBOBOX_ACQ, wxT ("Change the acquisition flag...")); 00044 this->ComboAcquisition ->SetWindowStyle (wxCB_DROPDOWN); 00045 this->ComboAcquisition ->Append (wxT("AXIAL")); 00046 this->ComboAcquisition ->Append (wxT("SAGITTAL")); 00047 this->ComboAcquisition ->Append (wxT("CORONAL")); 00048 this->ComboAcquisition ->SetSelection (0); 00049 00050 00051 this->ButtonFlipRL = new wxButton (this, BUTTON_FLIPRL, wxT("Flip R-L"), wxDefaultPosition, wxSize (64,64)); 00052 this->ButtonFlipFH = new wxButton (this, BUTTON_FLIPFH, wxT("Flip I-S"), wxDefaultPosition, wxSize (64,64)); 00053 this->ButtonFlipAP = new wxButton (this, BUTTON_FLIPAP, wxT("Flip A-P"), wxDefaultPosition, wxSize (64,64)); 00054 this->ButtonCANCEL = new wxButton (this, BUTTON_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize (80,30)); 00055 this->ButtonOK = new wxButton (this, BUTTON_OK, wxT("OK"), wxDefaultPosition, wxSize (80,30)); 00056 this->ButtonSave = new wxButton (this, BUTTON_SAVE, wxT("Save..."), wxDefaultPosition, wxSize (80,30)); 00057 00058 long viewstyle = wxWANTS_CHARS | wxNO_FULL_REPAINT_ON_RESIZE | wxSUNKEN_BORDER; 00059 00060 this->VtkView1 = new wxVTKRenderWindowInteractor (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle, wxT("")); 00061 this->VtkView2 = new wxVTKRenderWindowInteractor (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle, wxT("")); 00062 this->VtkView3 = new wxVTKRenderWindowInteractor (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle, wxT("")); 00063 00064 this->View1 = NIREPvtkViewImage2D::New(); //new wxNIREPNIREPvtkViewImage2D (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle, wxT(""), wxNIREPNIREPvtkViewImage2D::AXIAL_ID); 00065 this->View2 = NIREPvtkViewImage2D::New(); //new wxNIREPNIREPvtkViewImage2D (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle ); 00066 this->View3 = NIREPvtkViewImage2D::New(); //new wxNIREPNIREPvtkViewImage2D (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle ); 00067 00068 vtkRenderer* rend1 = vtkRenderer::New(); 00069 vtkRenderer* rend2 = vtkRenderer::New(); 00070 vtkRenderer* rend3 = vtkRenderer::New(); 00071 00072 this->VtkView1->GetRenderWindow()->AddRenderer (rend1); 00073 this->VtkView2->GetRenderWindow()->AddRenderer (rend2); 00074 this->VtkView3->GetRenderWindow()->AddRenderer (rend3); 00075 00076 this->View1->SetRenderWindow (this->VtkView1->GetRenderWindow()); 00077 this->View2->SetRenderWindow (this->VtkView2->GetRenderWindow()); 00078 this->View3->SetRenderWindow (this->VtkView3->GetRenderWindow()); 00079 00080 this->View1->SetRenderer (rend1); 00081 this->View2->SetRenderer (rend2); 00082 this->View3->SetRenderer (rend3); 00083 00084 rend1->Delete(); 00085 rend2->Delete(); 00086 rend3->Delete(); 00087 00088 00089 this->Image = 0; 00090 this->FirstRender = 0; 00091 00092 this->ImageDim[0] = 0; 00093 this->ImageDim[1] = 0; 00094 this->ImageDim[2] = 0; 00095 00096 this->ImageOrigin[0] = 0; 00097 this->ImageOrigin[1] = 0; 00098 this->ImageOrigin[2] = 0; 00099 00100 this->ImageCenter[0] = 0; 00101 this->ImageCenter[1] = 0; 00102 this->ImageCenter[2] = 0; 00103 00104 this->AcquisitionFlag = ACQ_AXIAL; 00105 00106 this->AxesFlipped[0] = 0; 00107 this->AxesFlipped[1] = 0; 00108 this->AxesFlipped[2] = 0; 00109 00110 this->Reslicer = vtkImageReslice::New(); 00111 this->Reslicer->InterpolateOff(); 00112 00113 this->SetProperties(); 00114 this->DoLayout(); 00115 00116 00117 } 00118 00119 wxVtkImageFlip::~wxVtkImageFlip() 00120 { 00121 this->View1->Detach(); 00122 this->View2->Detach(); 00123 this->View3->Detach(); 00124 00125 this->VtkView1->Delete(); 00126 this->VtkView2->Delete(); 00127 this->VtkView3->Delete(); 00128 00129 this->View1->Delete(); 00130 this->View2->Delete(); 00131 this->View3->Delete(); 00132 00133 this->Reslicer->Delete(); 00134 } 00135 00136 void wxVtkImageFlip::SetProperties() 00137 { 00138 00139 this->View1->SetBackgroundColor (0.0, 0.0, 0.0); 00140 this->View2->SetBackgroundColor (0.0, 0.0, 0.0); 00141 this->View3->SetBackgroundColor (0.0, 0.0, 0.0); 00142 00143 this->View1->SetAboutData ("AXIAL"); 00144 this->View2->SetAboutData ("CORONAL"); 00145 this->View3->SetAboutData ("SAGITTAL"); 00146 00147 this->View1->SetOrientation( NIREPvtkViewImage2D::AXIAL_ID); 00148 this->View2->SetOrientation( NIREPvtkViewImage2D::CORONAL_ID); 00149 this->View3->SetOrientation( NIREPvtkViewImage2D::SAGITTAL_ID); 00150 00151 this->View1->AddChild (this->View2); 00152 this->View2->AddChild (this->View3); 00153 this->View3->AddChild (this->View1); 00154 00155 this->View1->SetShowAnnotations (false); 00156 this->View2->SetShowAnnotations (false); 00157 this->View3->SetShowAnnotations (false); 00158 } 00159 00160 00161 void wxVtkImageFlip::DoLayout() 00162 { 00163 wxBoxSizer* sizermain = new wxBoxSizer(wxVERTICAL); 00164 00165 wxBoxSizer* sizerviews = new wxBoxSizer (wxHORIZONTAL); 00166 wxBoxSizer* sizerbuttons = new wxBoxSizer(wxHORIZONTAL); 00167 wxBoxSizer* sizerOK = new wxBoxSizer(wxHORIZONTAL); 00168 00169 sizerviews ->Add (this->VtkView1, 1, wxALL|wxEXPAND, 5); 00170 sizerviews ->Add (this->VtkView2, 1, wxALL|wxEXPAND, 5); 00171 sizerviews ->Add (this->VtkView3, 1, wxALL|wxEXPAND, 5); 00172 00173 sizerbuttons ->Add (this->AcquisitionTxt, 0, wxALL|wxFIXED_MINSIZE, 5); 00174 sizerbuttons ->Add (this->ComboAcquisition, 0, wxALL|wxFIXED_MINSIZE, 5); 00175 sizerbuttons ->Add (this->ButtonFlipFH, 0, wxALL|wxEXPAND, 5); 00176 sizerbuttons ->Add (this->ButtonFlipRL, 0, wxALL|wxEXPAND, 5); 00177 sizerbuttons ->Add (this->ButtonFlipAP, 0, wxALL|wxEXPAND, 5); 00178 00179 sizerOK ->Add (this->ButtonSave, 0, wxALL|wxEXPAND, 5); 00180 sizerOK ->Add (this->ButtonCANCEL, 0, wxALL|wxEXPAND, 5); 00181 sizerOK ->Add (this->ButtonOK, 0, wxALL|wxEXPAND, 5); 00182 00183 sizermain ->Add (sizerviews, 1, wxALL|wxEXPAND, 0); 00184 sizermain ->Add (sizerbuttons, 0, wxCENTER, 0); 00185 sizermain ->Add (sizerOK, 0, wxALIGN_RIGHT, 0); 00186 00187 00188 this->SetAutoLayout(true); 00189 this->SetSizerAndFit (sizermain); 00190 00191 this->SetSize (wxSize (700,400)); 00192 00193 this->Layout(); 00194 00195 } 00196 00197 00198 BEGIN_EVENT_TABLE (wxVtkImageFlip, wxDialog) 00199 EVT_COMBOBOX (COMBOBOX_ACQ, wxVtkImageFlip::OnComboAcquisition) 00200 EVT_BUTTON (BUTTON_FLIPRL, wxVtkImageFlip::OnButtonFlipRL) 00201 EVT_BUTTON (BUTTON_FLIPAP, wxVtkImageFlip::OnButtonFlipAP) 00202 EVT_BUTTON (BUTTON_FLIPFH, wxVtkImageFlip::OnButtonFlipFH) 00203 EVT_BUTTON (BUTTON_CANCEL, wxVtkImageFlip::OnButtonCANCEL) 00204 EVT_BUTTON (BUTTON_OK, wxVtkImageFlip::OnButtonOK) 00205 EVT_BUTTON (BUTTON_SAVE, wxVtkImageFlip::OnButtonSave) 00206 END_EVENT_TABLE() 00207 00208 00209 void wxVtkImageFlip::OnButtonFlipFH(wxCommandEvent &event) 00210 { 00211 if (!this->Image) 00212 return; 00213 00214 unsigned int direction = this->View1->GetOrthogonalAxis (NIREPvtkViewImage::AXIAL_ID); 00215 00216 this->AxesFlipped[direction] = !this->AxesFlipped[direction]; 00217 00218 this->UpdateReslicer(); 00219 this->Synchronize(); 00220 00221 } 00222 00223 00224 void wxVtkImageFlip::OnButtonFlipRL(wxCommandEvent &event) 00225 { 00226 if (!this->Image) 00227 return; 00228 00229 unsigned int direction = this->View1->GetOrthogonalAxis (NIREPvtkViewImage::SAGITTAL_ID); 00230 00231 this->AxesFlipped[direction] = !this->AxesFlipped[direction]; 00232 00233 this->UpdateReslicer(); 00234 this->Synchronize(); 00235 00236 } 00237 00238 void wxVtkImageFlip::OnButtonFlipAP(wxCommandEvent &event) 00239 { 00240 if (!this->Image) 00241 return; 00242 00243 unsigned int direction = this->View1->GetOrthogonalAxis (NIREPvtkViewImage::CORONAL_ID); 00244 00245 this->AxesFlipped[direction] = !this->AxesFlipped[direction]; 00246 00247 this->UpdateReslicer(); 00248 this->Synchronize(); 00249 } 00250 00251 00252 void wxVtkImageFlip::SetImage (vtkImageData* image) 00253 { 00254 if (!image) 00255 return; 00256 00257 this->Image = image; 00258 00259 image->GetDimensions (this->ImageDim); 00260 image->GetOrigin (this->ImageOrigin); 00261 image->GetCenter (this->ImageCenter); 00262 image->GetWholeExtent (this->ImageExtent); 00263 00264 00265 image->GetSpacing (this->ImageSpacing); 00266 00267 this->Reslicer->SetInput (image); 00268 00269 this->Reslicer->SetOutputExtentToDefault(); 00270 this->Reslicer->SetOutputSpacingToDefault(); 00271 this->Reslicer->SetOutputOriginToDefault(); 00272 00273 //Jeffrey Hawley 00274 //I moved the this->UpdateReslicer(); here and added in the 00275 //this->Reslicer->Update(); so that the View1->SetImage would 00276 //stop complaining about the Extents of the images being 0,-1, etc. 00277 this->UpdateReslicer(); 00278 this->Reslicer->Update(); 00279 this->View1->SetImage (this->Reslicer->GetOutput()); 00280 this->View2->SetImage (this->Reslicer->GetOutput()); 00281 this->View3->SetImage (this->Reslicer->GetOutput()); 00282 00283 //this->UpdateReslicer(); 00284 this->Synchronize(); 00285 00286 } 00287 00288 void wxVtkImageFlip::OnButtonSave (wxCommandEvent &event) 00289 { 00290 00291 if( !this->GetImage() ) 00292 { 00293 return; 00294 } 00295 00296 wxFileDialog* myFileDialog = new wxFileDialog(this, wxT("Save image as"), 00297 wxT(""), wxT(""), 00298 wxSupportedImageExtensionsFilter, 00299 wxFD_SAVE|wxFD_CHANGE_DIR|wxFD_OVERWRITE_PROMPT, wxDefaultPosition); 00300 wxString filename; 00301 filename.Empty(); 00302 int OK = myFileDialog->ShowModal(); 00303 00304 if( OK==wxID_OK ) 00305 { 00306 filename = myFileDialog->GetPath(); 00307 } 00308 myFileDialog->Destroy(); 00309 00310 if( filename.IsEmpty() ) 00311 { 00312 return; 00313 } 00314 00315 00316 switch( this->GetImage()->GetScalarType() ) 00317 { 00318 00319 case VTK_CHAR: 00320 this->SaveImage<itk::Image<char,3> > ( this->Reslicer->GetOutput(), filename.char_str() ); 00321 break; 00322 00323 case VTK_SIGNED_CHAR : 00324 this->SaveImage< itk::Image<unsigned char, 3> >( this->Reslicer->GetOutput(), filename.char_str()); 00325 break; 00326 00327 case VTK_SHORT : 00328 this->SaveImage< itk::Image<short, 3> >( this->Reslicer->GetOutput(), filename.char_str() ); 00329 break; 00330 00331 case VTK_UNSIGNED_SHORT : 00332 this->SaveImage< itk::Image<unsigned short, 3> >( this->Reslicer->GetOutput(), filename.char_str() ); 00333 break; 00334 00335 case VTK_INT : 00336 this->SaveImage< itk::Image<int, 3> >( this->Reslicer->GetOutput(), filename.char_str() ); 00337 break; 00338 00339 case VTK_UNSIGNED_INT : 00340 this->SaveImage< itk::Image<unsigned int, 3> >( this->Reslicer->GetOutput(), filename.char_str() ); 00341 break; 00342 00343 case VTK_LONG : 00344 this->SaveImage< itk::Image<long, 3> >( this->Reslicer->GetOutput(), filename.char_str() ); 00345 break; 00346 00347 case VTK_UNSIGNED_LONG : 00348 this->SaveImage< itk::Image<unsigned long, 3> >( this->Reslicer->GetOutput(), filename.char_str() ); 00349 break; 00350 00351 case VTK_FLOAT : 00352 this->SaveImage< itk::Image<float, 3> >( this->Reslicer->GetOutput(), filename.char_str() ); 00353 break; 00354 00355 case VTK_DOUBLE : 00356 this->SaveImage< itk::Image<double, 3> >( this->Reslicer->GetOutput(), filename.char_str() ); 00357 break; 00358 00359 default: 00360 wxMessageDialog* myDialog = new wxMessageDialog(this, wxT("Error: pixel type is not supported."), 00361 wxT ("Error"), 00362 wxOK|wxICON_ERROR); 00363 myDialog->ShowModal(); 00364 myDialog->Destroy(); 00365 } 00366 00367 00368 } 00369 00370 00371 void wxVtkImageFlip::OnButtonCANCEL (wxCommandEvent &event) 00372 { 00373 EndModal(wxID_CANCEL); 00374 } 00375 00376 void wxVtkImageFlip::OnButtonOK (wxCommandEvent &event) 00377 { 00378 EndModal(wxID_OK); 00379 } 00380 00381 void wxVtkImageFlip::OnComboAcquisition(wxCommandEvent &event) 00382 { 00383 unsigned int flag = this->ComboAcquisition->GetSelection(); 00384 this->AcquisitionFlag = flag; 00385 00386 this->UpdateReslicer(); 00387 this->Synchronize(); 00388 } 00389 00390 00391 void wxVtkImageFlip::UpdateReslicer (void) 00392 { 00393 if (!this->Image) 00394 { 00395 return; 00396 } 00397 00398 int newaxes[3] = { 0, 1, 2 }; 00399 double I[3][3] = { {1, 0, 0}, 00400 {0, 1, 0}, 00401 {0, 0, 1} }; 00402 00403 double resliceorigin[3] = { 0, 0, 0 }; 00404 00405 00406 00407 00408 switch (this->AcquisitionFlag) 00409 { 00410 case ACQ_AXIAL: 00411 break; 00412 case ACQ_CORONAL: 00413 //changed 00414 //newaxes[0] = 2; 00415 //newaxes[1] = 0; 00416 //newaxes[2] = 1; 00417 //This way when a user selects sagittal, you 00418 //actually get a sagittal view and not a 00419 //coronal view. 00420 //Jeffrey Hawley 00421 newaxes[0] = 1; 00422 newaxes[1] = 2; 00423 newaxes[2] = 0; 00424 break; 00425 case ACQ_SAGITTAL: 00426 newaxes[0] = 0; 00427 newaxes[1] = 2; 00428 newaxes[2] = 1; 00429 break; 00430 } 00431 00432 for (unsigned int i=0; i<3; i++) 00433 { 00434 if (AxesFlipped[i]) 00435 { 00436 I[newaxes[i]][newaxes[i]]=-1; 00437 resliceorigin[newaxes[i]] = 2*this->ImageOrigin[newaxes[i]] + 00438 this->ImageSpacing[newaxes[i]]* 00439 (this->ImageExtent[2*newaxes[i]] + this->ImageExtent[2*newaxes[i]+1]); 00440 } 00441 } 00442 00443 this->Reslicer->SetResliceAxesDirectionCosines( I[newaxes[0]], 00444 I[newaxes[1]], 00445 I[newaxes[2]]); 00446 00447 00448 this->Reslicer->SetResliceAxesOrigin (resliceorigin); 00449 00450 } 00451 00452 00453 void wxVtkImageFlip::Synchronize (void) 00454 { 00455 00456 if (!this->Image) 00457 return; 00458 00459 this->Reslicer->Modified(); 00460 this->Reslicer->UpdateWholeExtent(); 00461 //this->Reslicer->GetOutput()->UpdateInformation(); 00462 00463 this->View1->Update(); 00464 this->View2->Update(); 00465 this->View3->Update(); 00466 00467 this->View1->SyncResetCurrentPoint(); 00468 this->View1->SyncResetWindowLevel(); 00469 00470 this->View1->ResetCamera(); 00471 this->View2->ResetCamera(); 00472 this->View3->ResetCamera(); 00473 00474 if( !this->View1->GetRenderWindow()->GetNeverRendered() ) 00475 this->View1->Render(); 00476 if( !this->View2->GetRenderWindow()->GetNeverRendered() ) 00477 this->View2->Render(); 00478 if( !this->View1->GetRenderWindow()->GetNeverRendered() ) 00479 this->View2->Render(); 00480 00481 }