** 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
#include "backprojectors.h"
#include "reconstruct.h"
#include "timer.h"
+#include "threadrecon.h"
+
+#define CTSIM_THREADS 1
#if defined(MSVC) || HAVE_SSTREAM
#include <sstream>
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();
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);
}
}
} 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)) {
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,
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...");
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;
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()
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
}
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)) {
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...");
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");
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;
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)
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...");
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;