r589: Added threaded rasterizer
[ctsim.git] / src / views.cpp
index c94fa7ec453aac4706114fd477657cbaad93606c..fdfbc9f6dde82fd16e1d9576f4f5d87894a77454 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.120 2001/02/25 16:21:36 kevin Exp $
+**  $Id: views.cpp,v 1.121 2001/02/27 03:59:30 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
@@ -49,6 +49,7 @@
 #include "timer.h"
 #include "threadproj.h"
 #include "threadrecon.h"
+#include "threadraster.h"
 
 #if defined(MSVC) || HAVE_SSTREAM
 #include <sstream>
@@ -893,12 +894,12 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pMenuAnalyze->Append (IFMENU_PLOT_COL, "Plot &Column");
   m_pMenuAnalyze->Append (IFMENU_PLOT_HISTOGRAM, "Plot &Histogram");
   m_pMenuAnalyze->AppendSeparator();
-  m_pMenuAnalyze->Append (IFMENU_PLOT_FFT_ROW, "Plot FFT Row");
-  m_pMenuAnalyze->Append (IFMENU_PLOT_FFT_COL, "Plot FFT Column");
+  m_pMenuAnalyze->Append (IFMENU_PLOT_FFT_ROW, "P&lot FFT Row");
+  m_pMenuAnalyze->Append (IFMENU_PLOT_FFT_COL, "Plo&t FFT Column");
   m_pMenuAnalyze->AppendSeparator();
   m_pMenuAnalyze->Append (IFMENU_COMPARE_IMAGES, "Compare &Images...");
-  m_pMenuAnalyze->Append (IFMENU_COMPARE_ROW, "Compare &Row");
-  m_pMenuAnalyze->Append (IFMENU_COMPARE_COL, "Compare &Column");
+  m_pMenuAnalyze->Append (IFMENU_COMPARE_ROW, "Compare Ro&w");
+  m_pMenuAnalyze->Append (IFMENU_COMPARE_COL, "Compare Colu&mn");
   m_pMenuAnalyze->Enable (IFMENU_PLOT_ROW, false);
   m_pMenuAnalyze->Enable (IFMENU_PLOT_COL, false);
   m_pMenuAnalyze->Enable (IFMENU_COMPARE_ROW, false);
@@ -1997,56 +1998,64 @@ PhantomFileView::OnRasterize (wxCommandEvent& event)
   DialogGetRasterParameters dialogRaster (getFrameForChild(), m_iDefaultRasterNX, m_iDefaultRasterNY, 
     m_iDefaultRasterNSamples, m_dDefaultRasterViewRatio);
   int retVal = dialogRaster.ShowModal();
-  if (retVal == wxID_OK) {
-    m_iDefaultRasterNX = dialogRaster.getXSize();
-    m_iDefaultRasterNY  = dialogRaster.getYSize();
-    m_iDefaultRasterNSamples = dialogRaster.getNSamples();
-    m_dDefaultRasterViewRatio = dialogRaster.getViewRatio();
-    if (m_iDefaultRasterNSamples < 1)
-      m_iDefaultRasterNSamples = 1;
-    if (m_dDefaultRasterViewRatio < 0)
-      m_dDefaultRasterViewRatio = 0;
-    if (m_iDefaultRasterNX > 0 && m_iDefaultRasterNY > 0) {
-      const Phantom& rPhantom = GetDocument()->getPhantom();
-      
-      ImageFile* pImageFile = new ImageFile;
-      
-      pImageFile->setArraySize (m_iDefaultRasterNX, m_iDefaultRasterNY);
-      wxProgressDialog dlgProgress (wxString("Rasterize"), wxString("Rasterization Progress"), 
-        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, 
-          Trace::TRACE_NONE, i, 1, true);
-        if (! dlgProgress.Update (i+1)) {
-          delete pImageFile;
-          return;
-        }
-      }
-      
-      ImageFileDocument* pRasterDoc = theApp->newImageDoc();
-      if (! pRasterDoc) {
-        sys_error (ERR_SEVERE, "Unable to create image file");
+  if (retVal != wxID_OK)
+    return;
+  
+  m_iDefaultRasterNX = dialogRaster.getXSize();
+  m_iDefaultRasterNY  = dialogRaster.getYSize();
+  m_iDefaultRasterNSamples = dialogRaster.getNSamples();
+  m_dDefaultRasterViewRatio = dialogRaster.getViewRatio();
+  if (m_iDefaultRasterNSamples < 1)
+    m_iDefaultRasterNSamples = 1;
+  if (m_dDefaultRasterViewRatio < 0)
+    m_dDefaultRasterViewRatio = 0;
+  if (m_iDefaultRasterNX <= 0 || m_iDefaultRasterNY <= 0) 
+    return;
+  
+  const Phantom& rPhantom = GetDocument()->getPhantom();
+  std::ostringstream os;
+  os << "Rasterize Phantom " << rPhantom.name() << ": XSize=" << m_iDefaultRasterNX << ", YSize=" 
+    << m_iDefaultRasterNY << ", ViewRatio=" << m_dDefaultRasterViewRatio << ", nSamples=" 
+    << m_iDefaultRasterNSamples;;
+
+  if (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) {
+    RasterizerSupervisorThread* pThread = new RasterizerSupervisorThread (this, m_iDefaultRasterNX, m_iDefaultRasterNY,
+      m_dDefaultRasterViewRatio, m_iDefaultRasterNSamples, os.str().c_str());
+    if (pThread->Create() != wxTHREAD_NO_ERROR) {
+      *theApp->getLog() << "Error creating rasterizer thread\n";
+      return;
+    }
+    pThread->SetPriority (60);
+    pThread->Run();
+  } else {
+    ImageFile* pImageFile = new ImageFile (m_iDefaultRasterNX, m_iDefaultRasterNY);
+    wxProgressDialog dlgProgress (wxString("Rasterize"), wxString("Rasterization Progress"), 
+      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, Trace::TRACE_NONE, i, 1, true);
+      if (! dlgProgress.Update (i+1)) {
+        delete pImageFile;
         return;
       }
-      pRasterDoc->setImageFile (pImageFile);
-      
-      if (theApp->getAskDeleteNewDocs())
-        pRasterDoc->Modify (true);
-      pRasterDoc->UpdateAllViews (this);
-      pRasterDoc->getView()->getFrame()->Show(true);
-      std::ostringstream os;
-      os << "Rasterize Phantom " << rPhantom.name() << ": XSize=" << m_iDefaultRasterNX << ", YSize=" 
-        << m_iDefaultRasterNY << ", ViewRatio=" << m_dDefaultRasterViewRatio << ", nSamples=" 
-        << m_iDefaultRasterNSamples;;
-      *theApp->getLog() << os.str().c_str() << "\n";
-      pImageFile->labelAdd (os.str().c_str(), timer.timerEnd());
-      ImageFileView* rasterView = pRasterDoc->getView();
-      if (rasterView) {
-        rasterView->getFrame()->SetFocus();
-        rasterView->OnUpdate (rasterView, NULL);
-      }
-      
+    }
+  
+    ImageFileDocument* pRasterDoc = theApp->newImageDoc();
+    if (! pRasterDoc) {
+      sys_error (ERR_SEVERE, "Unable to create image file");
+      return;
+    }
+    pRasterDoc->setImageFile (pImageFile);
+    if (theApp->getAskDeleteNewDocs())
+      pRasterDoc->Modify (true);
+    pRasterDoc->UpdateAllViews (this);
+    pRasterDoc->getView()->getFrame()->Show(true);
+    *theApp->getLog() << os.str().c_str() << "\n";
+    pImageFile->labelAdd (os.str().c_str(), timer.timerEnd());
+    ImageFileView* rasterView = pRasterDoc->getView();
+    if (rasterView) {
+      rasterView->getFrame()->SetFocus();
+      rasterView->OnUpdate (rasterView, NULL);
     }
   }
 }
@@ -2418,20 +2427,19 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
   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;
+  ImageFile rImageFile;
   if (m_iDefaultTrace > Trace::TRACE_CONSOLE) {
-    ImageFile* pImageFile = new ImageFile;
-    pImageFile->setArraySize (m_iDefaultNX, m_iDefaultNY);
-    Reconstructor* pReconstructor = new Reconstructor (rProj, *pImageFile, optFilterName.c_str(), 
+    rImageFile.setArraySize (m_iDefaultNX, m_iDefaultNY);
+    Reconstructor* pReconstructor = new Reconstructor (rProj, rImageFile, 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());
+    ReconstructDialog* pDlgReconstruct = new ReconstructDialog (*pReconstructor, rProj, rImageFile, 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();
@@ -2444,24 +2452,6 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
     pReconstructor->postProcessing();
     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 (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) {
       ReconstructorSupervisorThread* pReconstructor = new ReconstructorSupervisorThread (this, 
@@ -2475,10 +2465,10 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
       }
       pReconstructor->SetPriority (60);
       pReconstructor->Run();
+      return;
     } else {
-      ImageFile* pImageFile = new ImageFile;
-      pImageFile->setArraySize (m_iDefaultNX, m_iDefaultNY);
-      Reconstructor* pReconstructor = new Reconstructor (rProj, *pImageFile, optFilterName.c_str(), 
+      rImageFile.setArraySize (m_iDefaultNX, m_iDefaultNY);
+      Reconstructor* pReconstructor = new Reconstructor (rProj, rImageFile, optFilterName.c_str(), 
         m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
         optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace);
       
@@ -2487,8 +2477,7 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
         pReconstructor->reconstructView (iView, 1);
         if (! dlgProgress.Update (iView + 1)) {
           delete pReconstructor;
-          delete pImageFile;
-          return;
+          return; // don't make new window, thread will do this
         }
       }
       pReconstructor->postProcessing();
@@ -2498,20 +2487,25 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
         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());
     }
   }
+  ImageFileDocument* pReconDoc = theApp->newImageDoc();
+  if (! pReconDoc) {
+    sys_error (ERR_SEVERE, "Unable to create image file");
+    return;
+  }
+  pReconDoc->setImageFile (&rImageFile);
+  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";
+  rImageFile.labelAdd (rProj.getLabel());
+  rImageFile.labelAdd (os.str().c_str(), timerRecon.timerEnd());    
 }