r571: no message
[ctsim.git] / src / views.cpp
index c20009dbf38813fec99bc18711f64237e2527678..60eda6ab2633d86c0a31d26d655185bc1a3e4958 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.111 2001/02/22 00:56:50 kevin Exp $
+**  $Id: views.cpp,v 1.112 2001/02/22 11:05:38 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ******************************************************************************/
 
-// For compilers that support precompilation, includes "wx/wx.h".
 #include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
 #ifndef WX_PRECOMP
 #include "wx/wx.h"
 #endif
@@ -53,6 +47,9 @@
 #include "backprojectors.h"
 #include "reconstruct.h"
 #include "timer.h"
+#include "threadrecon.h"
+
+#define CTSIM_THREADS 1
 
 #if defined(MSVC) || HAVE_SSTREAM
 #include <sstream>
@@ -835,7 +832,7 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_REVERT, "Re&vert");
   
   m_pFileMenu->AppendSeparator();
-  m_pFileMenu->Append(IFMENU_FILE_PROPERTIES, "P&roperties");
+  m_pFileMenu->Append(IFMENU_FILE_PROPERTIES, "P&roperties\tCtrl-I");
   m_pFileMenu->Append(IFMENU_FILE_EXPORT, "&Export...");
   
   m_pFileMenu->AppendSeparator();
@@ -928,15 +925,16 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   
   subframe->Centre(wxBOTH);
   
-  wxAcceleratorEntry accelEntries[4];
+  wxAcceleratorEntry accelEntries[5];
   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('A'), IFMENU_VIEW_SCALE_AUTO);
   accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('U'), IFMENU_VIEW_SCALE_FULL);
   accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('E'), IFMENU_VIEW_SCALE_MINMAX);
+  accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('I'), IFMENU_FILE_PROPERTIES);
 #if wxUSE_GLCANVAS
-  accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('3'), IFMENU_IMAGE_CONVERT3D);
-  wxAcceleratorTable accelTable (4, accelEntries);
+  accelEntries[4].Set (wxACCEL_CTRL, static_cast<int>('3'), IFMENU_IMAGE_CONVERT3D);
+  wxAcceleratorTable accelTable (5, accelEntries);
 #else
-  wxAcceleratorTable accelTable (3, accelEntries);
+  wxAcceleratorTable accelTable (4, accelEntries);
 #endif
 
   subframe->SetAcceleratorTable (accelTable);
@@ -1920,7 +1918,7 @@ PhantomFileView::OnProjections (wxCommandEvent& event)
           }
         }
       } else {
-        wxProgressDialog dlgProgress (wxString("Projection"), wxString("Projection Progress"), pProj->nView() + 1, getFrameForChild(), wxPD_CAN_ABORT);
+        wxProgressDialog dlgProgress (wxString("Projection"), wxString("Projection Progress"), pProj->nView() + 1, getFrameForChild(), wxPD_CAN_ABORT );
         for (int i = 0; i < pProj->nView(); i++) {
           theScanner.collectProjections (*pProj, rPhantom, i, 1, true, m_iDefaultTrace);
           if (! dlgProgress.Update (i+1)) {
@@ -1991,7 +1989,7 @@ PhantomFileView::OnRasterize (wxCommandEvent& event)
       
       pImageFile->setArraySize (m_iDefaultRasterNX, m_iDefaultRasterNY);
       wxProgressDialog dlgProgress (wxString("Rasterize"), wxString("Rasterization Progress"), 
-                                    pImageFile->nx() + 1, getFrameForChild(), wxPD_CAN_ABORT);
+                                    pImageFile->nx() + 1, getFrameForChild(), wxPD_CAN_ABORT );
       Timer timer;
       for (unsigned int i = 0; i < pImageFile->nx(); i++) {
         rPhantom.convertToImagefile (*pImageFile, m_dDefaultRasterViewRatio, m_iDefaultRasterNSamples, 
@@ -2065,7 +2063,7 @@ PhantomFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_CLOSE, "&Close");
   
   m_pFileMenu->AppendSeparator();
-  m_pFileMenu->Append(PHMMENU_FILE_PROPERTIES, "P&roperties");
+  m_pFileMenu->Append(PHMMENU_FILE_PROPERTIES, "P&roperties\tCtrl-I");
   
   m_pFileMenu->AppendSeparator();
   m_pFileMenu->Append(wxID_PRINT, "&Print...");
@@ -2098,10 +2096,11 @@ PhantomFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   subframe->SetMenuBar(menu_bar);
   subframe->Centre(wxBOTH);
   
-  wxAcceleratorEntry accelEntries[2];
+  wxAcceleratorEntry accelEntries[3];
   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('J'), PHMMENU_PROCESS_PROJECTIONS);
   accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('R'), PHMMENU_PROCESS_RASTERIZE);
-  wxAcceleratorTable accelTable (2, accelEntries);
+  accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('I'), PHMMENU_FILE_PROPERTIES);
+  wxAcceleratorTable accelTable (3, accelEntries);
   subframe->SetAcceleratorTable (accelTable);
   
   return subframe;
@@ -2218,6 +2217,7 @@ IMPLEMENT_DYNAMIC_CLASS(ProjectionFileView, wxView)
 BEGIN_EVENT_TABLE(ProjectionFileView, wxView)
 EVT_MENU(PJMENU_FILE_PROPERTIES, ProjectionFileView::OnProperties)
 EVT_MENU(PJMENU_RECONSTRUCT_FBP, ProjectionFileView::OnReconstructFBP)
+EVT_MENU(PJMENU_RECONSTRUCT_FOURIER, ProjectionFileView::OnReconstructFourier)
 EVT_MENU(PJMENU_CONVERT_POLAR, ProjectionFileView::OnConvertPolar)
 EVT_MENU(PJMENU_CONVERT_FFT_POLAR, ProjectionFileView::OnConvertFFTPolar)
 END_EVENT_TABLE()
@@ -2354,7 +2354,132 @@ ProjectionFileView::OnConvertFFTPolar (wxCommandEvent& event)
 void
 ProjectionFileView::OnReconstructFourier (wxCommandEvent& event)
 {
+#if CTSIM_THREADS
+  DialogGetReconstructionParameters dialogReconstruction (getFrameForChild(), m_iDefaultNX, m_iDefaultNY, 
+    m_iDefaultFilter, m_dDefaultFilterParam, m_iDefaultFilterMethod, m_iDefaultFilterGeneration, 
+    m_iDefaultZeropad, m_iDefaultInterpolation, m_iDefaultInterpParam, m_iDefaultBackprojector, 
+    m_iDefaultTrace);
+  
+  int retVal = dialogReconstruction.ShowModal();
+  if (retVal == wxID_OK) {
+    m_iDefaultNX = dialogReconstruction.getXSize();
+    m_iDefaultNY = dialogReconstruction.getYSize();
+    wxString optFilterName = dialogReconstruction.getFilterName();
+    m_iDefaultFilter = SignalFilter::convertFilterNameToID (optFilterName.c_str());
+    m_dDefaultFilterParam = dialogReconstruction.getFilterParam();
+    wxString optFilterMethodName = dialogReconstruction.getFilterMethodName();
+    m_iDefaultFilterMethod = ProcessSignal::convertFilterMethodNameToID(optFilterMethodName.c_str());
+    m_iDefaultZeropad = dialogReconstruction.getZeropad();
+    wxString optFilterGenerationName = dialogReconstruction.getFilterGenerationName();
+    m_iDefaultFilterGeneration = ProcessSignal::convertFilterGenerationNameToID (optFilterGenerationName.c_str());
+    wxString optInterpName = dialogReconstruction.getInterpName();
+    m_iDefaultInterpolation = Backprojector::convertInterpNameToID (optInterpName.c_str());
+    m_iDefaultInterpParam = dialogReconstruction.getInterpParam();
+    wxString optBackprojectName = dialogReconstruction.getBackprojectName();
+    m_iDefaultBackprojector = Backprojector::convertBackprojectNameToID (optBackprojectName.c_str());
+    m_iDefaultTrace = dialogReconstruction.getTrace();
+
+    if (m_iDefaultNX > 0 && m_iDefaultNY > 0) {
+      const Projections& rProj = GetDocument()->getProjections();
+      ImageFile* pImageFile = new ImageFile;
+      pImageFile->setArraySize (m_iDefaultNX, m_iDefaultNY);
+      std::ostringstream os;
+      os << "Reconstruct " << rProj.getFilename() << ": xSize=" << m_iDefaultNX << ", ySize=" << m_iDefaultNY << ", Filter=" << optFilterName.c_str() << ", FilterParam=" << m_dDefaultFilterParam << ", FilterMethod=" << optFilterMethodName.c_str() << ", FilterGeneration=" << optFilterGenerationName.c_str() << ", Zeropad=" << m_iDefaultZeropad << ", Interpolation=" << optInterpName.c_str() << ", InterpolationParam=" << m_iDefaultInterpParam << ", Backprojection=" << optBackprojectName.c_str();
+      
+      Timer timerRecon;
+      if (m_iDefaultTrace > Trace::TRACE_CONSOLE) {
+        Reconstructor* pReconstructor = new Reconstructor (rProj, *pImageFile, optFilterName.c_str(), 
+        m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
+        optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace);
+      
+        ReconstructDialog* pDlgReconstruct = new ReconstructDialog (*pReconstructor, rProj, *pImageFile, m_iDefaultTrace, getFrameForChild());
+        for (int iView = 0; iView < rProj.nView(); iView++) {
+          ::wxYield();
+          if (pDlgReconstruct->isCancelled() || ! pDlgReconstruct->reconstructView (iView, true)) {
+            delete pDlgReconstruct;
+            delete pReconstructor;
+            delete pImageFile;
+            return;
+          }
+          ::wxYield();
+          ::wxYield();
+          while (pDlgReconstruct->isPaused()) {
+            ::wxYield();
+            ::wxUsleep(50);
+          }
+        }
+        delete pDlgReconstruct;
+        delete pReconstructor;
+      ImageFileDocument* pReconDoc = theApp->newImageDoc();
+      if (! pReconDoc) {
+        sys_error (ERR_SEVERE, "Unable to create image file");
+        return;
+      }
+      pReconDoc->setImageFile (pImageFile);
+      if (theApp->getAskDeleteNewDocs())
+        pReconDoc->Modify (true);
+      pReconDoc->UpdateAllViews (this);
+      if (ImageFileView* rasterView = pReconDoc->getView()) {
+        rasterView->OnUpdate (rasterView, NULL);
+        rasterView->getFrame()->SetFocus();
+        rasterView->getFrame()->Show(true);
+      }
+      *theApp->getLog() << os.str().c_str() << "\n";
+      pImageFile->labelAdd (rProj.getLabel());
+      pImageFile->labelAdd (os.str().c_str(), timerRecon.timerEnd());
+
+      } else {
+#if CTSIM_THREADS
+        ThreadedReconstructor* pReconstructor = new ThreadedReconstructor (this, 
+        m_iDefaultNX, m_iDefaultNY, optFilterName.c_str(), 
+        m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
+        optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), os.str().c_str());
+        if (! pReconstructor->start()) {
+          delete pImageFile;
+          delete pReconstructor;
+          return;
+        }
+        delete pImageFile;
+        // delete pReconstructor;
+#else
+        Reconstructor* pReconstructor = new Reconstructor (rProj, *pImageFile, optFilterName.c_str(), 
+        m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
+        optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace);
+      
+        wxProgressDialog dlgProgress (wxString("Reconstruction"), wxString("Reconstruction Progress"), rProj.nView() + 1, getFrameForChild(), wxPD_CAN_ABORT );
+        for (int iView = 0; iView < rProj.nView(); iView++) {
+          pReconstructor->reconstructView (iView, 1);
+          if (! dlgProgress.Update (iView + 1)) {
+            delete pReconstructor;
+            delete pImageFile;
+            return;
+          }
+        }
+      delete pReconstructor;
+      ImageFileDocument* pReconDoc = theApp->newImageDoc();
+      if (! pReconDoc) {
+        sys_error (ERR_SEVERE, "Unable to create image file");
+        return;
+      }
+      pReconDoc->setImageFile (pImageFile);
+      if (theApp->getAskDeleteNewDocs())
+        pReconDoc->Modify (true);
+      pReconDoc->UpdateAllViews (this);
+      if (ImageFileView* rasterView = pReconDoc->getView()) {
+        rasterView->OnUpdate (rasterView, NULL);
+        rasterView->getFrame()->SetFocus();
+        rasterView->getFrame()->Show(true);
+      }
+      *theApp->getLog() << os.str().c_str() << "\n";
+      pImageFile->labelAdd (rProj.getLabel());
+      pImageFile->labelAdd (os.str().c_str(), timerRecon.timerEnd());
+#endif
+      }
+    }
+  }
+#else
   wxMessageBox ("Fourier Reconstruction is not yet supported", "Unimplemented function");
+#endif
 }
 
 void
@@ -2413,7 +2538,7 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
         }
         delete pDlgReconstruct;
       } else {
-        wxProgressDialog dlgProgress (wxString("Reconstruction"), wxString("Reconstruction Progress"), rProj.nView() + 1, getFrameForChild(), wxPD_CAN_ABORT);
+        wxProgressDialog dlgProgress (wxString("Reconstruction"), wxString("Reconstruction Progress"), rProj.nView() + 1, getFrameForChild(), wxPD_CAN_ABORT );
         for (int iView = 0; iView < rProj.nView(); iView++) {
           pReconstructor->reconstructView (iView, 1);
           if (! dlgProgress.Update (iView + 1)) {
@@ -2488,7 +2613,7 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_CLOSE, "&Close\tCtrl-W");
   
   m_pFileMenu->AppendSeparator();
-  m_pFileMenu->Append(PJMENU_FILE_PROPERTIES, "P&roperties");
+  m_pFileMenu->Append(PJMENU_FILE_PROPERTIES, "P&roperties\tCtrl-I");
   
   m_pFileMenu->AppendSeparator();
   m_pFileMenu->Append(wxID_PRINT, "&Print...");
@@ -2504,13 +2629,15 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   
   wxMenu *convert_menu = new wxMenu;
   convert_menu->Append (PJMENU_CONVERT_POLAR, "&Polar Image...\tCtrl-L");
-  convert_menu->Append (PJMENU_CONVERT_FFT_POLAR, "&FFT->Polar Image...\tCtrl-I");
+  convert_menu->Append (PJMENU_CONVERT_FFT_POLAR, "&FFT->Polar Image...\tCtrl-M");
   
   wxMenu *reconstruct_menu = new wxMenu;
   reconstruct_menu->Append (PJMENU_RECONSTRUCT_FBP, "&Filtered Backprojection...\tCtrl-R", "Reconstruct image using filtered backprojection");
   reconstruct_menu->Append (PJMENU_RECONSTRUCT_FOURIER, "&Fourier...\tCtrl-E", "Reconstruct image using inverse Fourier");
+#ifndef CTSIM_THREADS
   reconstruct_menu->Enable (PJMENU_RECONSTRUCT_FOURIER, false);
-  
+#endif
+
   wxMenu *help_menu = new wxMenu;
   help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents\tF1");
   help_menu->Append (MAINMENU_HELP_TIPS, "&Tips");
@@ -2527,12 +2654,13 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   subframe->SetMenuBar(menu_bar);  
   subframe->Centre(wxBOTH);
   
-  wxAcceleratorEntry accelEntries[4];
+  wxAcceleratorEntry accelEntries[5];
   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('L'), PJMENU_CONVERT_POLAR);
-  accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('I'), PJMENU_CONVERT_FFT_POLAR);
+  accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('M'), PJMENU_CONVERT_FFT_POLAR);
   accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('R'), PJMENU_RECONSTRUCT_FBP);
   accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('E'), PJMENU_RECONSTRUCT_FOURIER);
-  wxAcceleratorTable accelTable (4, accelEntries);
+  accelEntries[4].Set (wxACCEL_CTRL, static_cast<int>('I'), PJMENU_FILE_PROPERTIES);
+  wxAcceleratorTable accelTable (5, accelEntries);
   subframe->SetAcceleratorTable (accelTable);
   
   return subframe;
@@ -2680,7 +2808,7 @@ PlotFileCanvas::OnDraw(wxDC& dc)
 IMPLEMENT_DYNAMIC_CLASS(PlotFileView, wxView)
 
 BEGIN_EVENT_TABLE(PlotFileView, wxView)
-EVT_MENU(PJMENU_FILE_PROPERTIES, PlotFileView::OnProperties)
+EVT_MENU(PLOTMENU_FILE_PROPERTIES, PlotFileView::OnProperties)
 EVT_MENU(PLOTMENU_VIEW_SCALE_MINMAX, PlotFileView::OnScaleMinMax)
 EVT_MENU(PLOTMENU_VIEW_SCALE_AUTO, PlotFileView::OnScaleAuto)
 EVT_MENU(PLOTMENU_VIEW_SCALE_FULL, PlotFileView::OnScaleFull)
@@ -2813,7 +2941,7 @@ PlotFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_CLOSE, "&Close\tCtrl-W");
   
   m_pFileMenu->AppendSeparator();
-  m_pFileMenu->Append(PJMENU_FILE_PROPERTIES, "P&roperties");
+  m_pFileMenu->Append(PLOTMENU_FILE_PROPERTIES, "P&roperties\tCtrl-I");
   
   m_pFileMenu->AppendSeparator();
   m_pFileMenu->Append(wxID_PRINT, "&Print...");
@@ -2847,11 +2975,12 @@ PlotFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   subframe->SetMenuBar(menu_bar);
   subframe->Centre(wxBOTH);
   
-  wxAcceleratorEntry accelEntries[3];
+  wxAcceleratorEntry accelEntries[4];
   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('E'), PLOTMENU_VIEW_SCALE_MINMAX);
   accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('A'), PLOTMENU_VIEW_SCALE_AUTO);
   accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('U'), PLOTMENU_VIEW_SCALE_FULL);
-  wxAcceleratorTable accelTable (3, accelEntries);
+  accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('I'), PLOTMENU_FILE_PROPERTIES);
+  wxAcceleratorTable accelTable (4, accelEntries);
   subframe->SetAcceleratorTable (accelTable);
   
   return subframe;