From c6cda8844a491b71759e5dd5edba830d0b809cfd Mon Sep 17 00:00:00 2001 From: "Kevin M. Rosenberg" Date: Sat, 6 Jan 2001 15:33:15 +0000 Subject: [PATCH] r355: Polar conversions of projections --- ChangeLog | 6 +- include/imagefile.h | 6 +- libctsim/imagefile.cpp | 133 ++++++++++++++++++- libctsim/projections.cpp | 127 +++++++++--------- msvc/ctsim/ctsim.dsp | 9 +- msvc/ctsim/ctsim.plg | 18 +-- src/ctsim.cpp | 22 +++- src/ctsim.h | 23 +++- src/docs.cpp | 4 +- src/views.cpp | 276 +++++++++++++++++++++++++++++++++++---- src/views.h | 14 +- 11 files changed, 513 insertions(+), 125 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e0220b..cf77c83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,13 @@ -3.0.0beta1 - Released +3.0.0alpha4 * ctsim: Fixed initialization of min/max for PlotFiles * ctsim: Added reset to full-intensity scale menu item - * ctsim: Add convert projections to polar plot + * ctsim: Add conversion of projections to polar plot + * ctsim: improve bilinear scaling of image size + * ezplot: Cleaned up y-tick label placement * sgp: Added better support for projection/reconstruction animation diff --git a/include/imagefile.h b/include/imagefile.h index aabb903..a31b04e 100644 --- a/include/imagefile.h +++ b/include/imagefile.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: imagefile.h,v 1.29 2001/01/04 21:28:41 kevin Exp $ +** $Id: imagefile.h,v 1.30 2001/01/06 15:33:15 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 @@ -182,6 +182,10 @@ public: #ifdef HAVE_FFTW bool fft (ImageFile& result) const; bool ifft (ImageFile& result) const; + bool fftRows (ImageFile& result) const; + bool ifftRows (ImageFile& result) const; + bool fftCols (ImageFile& result) const; + bool ifftCols (ImageFile& result) const; #endif bool magnitude (ImageFile& result) const; bool phase (ImageFile& result) const; diff --git a/libctsim/imagefile.cpp b/libctsim/imagefile.cpp index 946e4db..37eaa8f 100644 --- a/libctsim/imagefile.cpp +++ b/libctsim/imagefile.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: imagefile.cpp,v 1.34 2001/01/04 21:28:41 kevin Exp $ +** $Id: imagefile.cpp,v 1.35 2001/01/06 15:33:15 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 @@ -701,14 +701,16 @@ ImageFile::scaleImage (ImageFile& result) const vResultImag[ix][iy] = 0; } } else { - vResult[ix][iy] = vReal[scaleNX][scaleNY] + - dXFrac * (vReal[scaleNX+1][scaleNY] - vReal[scaleNX][scaleNY]) + - dYFrac * (vReal[scaleNX][scaleNY+1] - vReal[scaleNX][scaleNY]); + vResult[ix][iy] = (1 - dXFrac) * (1 - dYFrac) * vReal[scaleNX][scaleNY] + + dXFrac * (1 - dYFrac) * vReal[scaleNX+1][scaleNY] + + dYFrac * (1 - dXFrac) * vReal[scaleNX][scaleNY+1] + + dXFrac * dYFrac * vReal[scaleNX+1][scaleNY+1]; if (result.isComplex()) { if (isComplex()) - vResultImag[ix][iy] = vImag[scaleNX][scaleNY] + - dXFrac * (vImag[scaleNX+1][scaleNY] - vImag[scaleNX][scaleNY]) + - dYFrac * (vImag[scaleNX][scaleNY+1] - vImag[scaleNX][scaleNY]); + vResultImag[ix][iy] = (1 - dXFrac) * (1 - dYFrac) * vImag[scaleNX][scaleNY] + + dXFrac * (1 - dYFrac) * vImag[scaleNX+1][scaleNY] + + dYFrac * (1 - dXFrac) * vImag[scaleNX][scaleNY+1] + + dXFrac * dYFrac * vImag[scaleNX+1][scaleNY+1]; else vResultImag[ix][iy] = 0; } @@ -832,6 +834,123 @@ ImageFile::ifft (ImageFile& result) const return true; } + +bool +ImageFile::fftRows (ImageFile& result) const +{ + if (m_nx != result.nx() || m_ny != result.ny()) { + sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::fftRows]"); + return false; + } + + if (result.dataType() == Array2dFile::DATA_TYPE_REAL) { + if (! result.convertRealToComplex ()) + return false; + } + + fftw_complex* in = new fftw_complex [m_nx]; + + ImageFileArrayConst vReal = getArray(); + ImageFileArrayConst vImag = getImaginaryArray(); + + fftw_plan plan = fftw_create_plan (m_nx, FFTW_FORWARD, FFTW_IN_PLACE); + std::complex* pcRow = new std::complex [m_nx]; + + unsigned int ix, iy; + unsigned int iArray = 0; + for (iy = 0; iy < m_ny; iy++) { + for (ix = 0; ix < m_nx; ix++) { + in[ix].re = vReal[ix][iy]; + if (isComplex()) + in[ix].im = vImag[ix][iy]; + else + in[ix].im = 0; + } + + fftw_one (plan, in, NULL); + + for (ix = 0; ix < m_nx; ix++) + pcRow[ix] = std::complex(in[ix].re, in[ix].im); + + Fourier::shuffleFourierToNaturalOrder (pcRow, m_nx); + for (ix = 0; ix < m_nx; ix++) { + vReal[ix][iy] = pcRow[ix].real(); + vImag[ix][iy] = pcRow[ix].imag(); + } + } + delete [] pcRow; + + fftw_destroy_plan (plan); + delete in; + + return true; +} + +bool +ImageFile::ifftRows (ImageFile& result) const +{ + if (m_nx != result.nx() || m_ny != result.ny()) { + sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::fftRows]"); + return false; + } + + if (result.dataType() == Array2dFile::DATA_TYPE_REAL) { + if (! result.convertRealToComplex ()) + return false; + } + + fftw_complex* in = new fftw_complex [m_nx]; + + ImageFileArrayConst vReal = getArray(); + ImageFileArrayConst vImag = getImaginaryArray(); + + fftw_plan plan = fftw_create_plan (m_nx, FFTW_BACKWARD, FFTW_IN_PLACE); + std::complex* pcRow = new std::complex [m_nx]; + + unsigned int ix, iy; + unsigned int iArray = 0; + for (iy = 0; iy < m_ny; iy++) { + for (ix = 0; ix < m_nx; ix++) { + double dImag = 0; + if (isComplex()) + dImag = vImag[ix][iy]; + pcRow[ix] = std::complex (vReal[ix][iy], dImag); + } + + Fourier::shuffleNaturalToFourierOrder (pcRow, m_nx); + + for (ix = 0; ix < m_nx; ix++) { + in[ix].re = pcRow[ix].real(); + in[ix].im = pcRow[ix].imag(); + } + + fftw_one (plan, in, NULL); + + for (ix = 0; ix < m_nx; ix++) { + vReal[ix][iy] = in[ix].re; + vImag[ix][iy] = in[ix].im; + } + } + delete [] pcRow; + + fftw_destroy_plan (plan); + delete in; + + return true; +} + +bool +ImageFile::fftCols (ImageFile& result) const +{ + return false; +} + +bool +ImageFile::ifftCols (ImageFile& result) const +{ + return false; +} + #endif // HAVE_FFTW diff --git a/libctsim/projections.cpp b/libctsim/projections.cpp index bdf6073..2217150 100644 --- a/libctsim/projections.cpp +++ b/libctsim/projections.cpp @@ -8,7 +8,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: projections.cpp,v 1.37 2001/01/04 21:28:41 kevin Exp $ +** $Id: projections.cpp,v 1.38 2001/01/06 15:33:15 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 @@ -37,14 +37,14 @@ const char* Projections::s_aszInterpName[] = { {"nearest"}, {"bilinear"}, - {"bicubic"}, +// {"bicubic"}, }; const char* Projections::s_aszInterpTitle[] = { {"Nearest"}, {"Bilinear"}, - {"Bicubic"}, +// {"Bicubic"}, }; const int Projections::s_iInterpCount = sizeof(s_aszInterpName) / sizeof(char*); @@ -696,6 +696,58 @@ Projections::convertPolar (ImageFile& rIF, int iInterpolationID) return true; } + +bool +Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad) +{ + unsigned int nx = rIF.nx(); + unsigned int ny = rIF.ny(); + ImageFileArray v = rIF.getArray(); + if (! rIF.isComplex()) + rIF.convertRealToComplex(); + ImageFileArray vImag = rIF.getImaginaryArray(); + + if (! v || nx == 0 || ny == 0) + return false; + + Array2d adView (nx, ny); + Array2d adDet (nx, ny); + double** ppdView = adView.getArray(); + double** ppdDet = adDet.getArray(); + + std::complex** ppcDetValue = new std::complex* [m_nView]; + unsigned int iView; + double* pdDet = new double [m_nDet]; + fftw_complex* pcIn = new fftw_complex [m_nDet]; + fftw_plan plan = fftw_create_plan (m_nDet, FFTW_FORWARD, FFTW_IN_PLACE); + + for (iView = 0; iView < m_nView; iView++) { + ppcDetValue[iView] = new std::complex [m_nDet]; + unsigned int iDet; + for (iDet = 0; iDet < m_nDet; iDet++) { + pcIn[iDet].re = getDetectorArray(iView).detValues()[iDet]; + pcIn[iDet].im = 0; + } + fftw_one (plan, pcIn, NULL); + for (iDet = 0; iDet < m_nDet; iDet++) + ppcDetValue[iView][iDet] = std::complex (pcIn[iDet].re, pcIn[iDet].im); + Fourier::shuffleFourierToNaturalOrder (ppcDetValue[iView], m_nDet); + } + + fftw_destroy_plan (plan); + delete [] pcIn; + + calcArrayPolarCoordinates (nx, ny, ppdView, ppdDet); + + interpolatePolar (v, vImag, nx, ny, ppcDetValue, ppdView, ppdDet, m_nView, m_nDet, iInterpolationID); + + for (iView = 0; iView < m_nView; iView++) + delete [] ppcDetValue[iView]; + delete [] ppcDetValue; + + return true; +} + void Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double** ppdView, double** ppdDet) { @@ -743,8 +795,10 @@ Projections::interpolatePolar (ImageFileArray& v, ImageFileArray& vImag, if (iInterpolationID == POLAR_INTERP_NEAREST) { int iView = nearest (ppdView[ix][iy]); int iDet = nearest (ppdDet[ix][iy]); - if (iView == nView) - iView = nView - 1; + if (iView == nView) { + iView = 0; + // iDet = m_nDet - iDet; + } if (iDet >= 0 && iDet < nDet && iView >= 0 && iView < nView) { v[ix][iy] = ppcDetValue[iView][iDet].real(); if (vImag) @@ -766,7 +820,7 @@ Projections::interpolatePolar (ImageFileArray& v, ImageFileArray& vImag, if (iFloorView < nView - 1) v2 = ppcDetValue[iFloorView + 1][iFloorDet]; else - v2 = v1; + v2 = ppcDetValue[0][iFloorDet]; if (iFloorDet < nDet - 1) v4 = ppcDetValue[iFloorView][iFloorDet+1]; else @@ -774,10 +828,12 @@ Projections::interpolatePolar (ImageFileArray& v, ImageFileArray& vImag, if (iFloorView < nView - 1 && iFloorDet < nDet - 1) v3 = ppcDetValue [iFloorView+1][iFloorDet+1]; else if (iFloorView < nView - 1) - v4 = v2; + v3 = v2; else - v4 = v1; - std::complex vInterp = v1 + dFracView * (v2 - v1) + dFracDet * (v4 - v1); + v3 = ppcDetValue[0][iFloorDet+1]; + std::complex vInterp = (1 - dFracView) * (1 - dFracDet) * v1 + + dFracView * (1 - dFracDet) * v2 + dFracView * dFracDet * v3 + + dFracDet * (1 - dFracView) * v4; v[ix][iy] = vInterp.real(); if (vImag) vImag[ix][iy] = vInterp.imag(); @@ -797,57 +853,4 @@ Projections::interpolatePolar (ImageFileArray& v, ImageFileArray& vImag, } } -bool -Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad) -{ - unsigned int nx = rIF.nx(); - unsigned int ny = rIF.ny(); - ImageFileArray v = rIF.getArray(); - if (! rIF.isComplex()) - rIF.convertRealToComplex(); - ImageFileArray vImag = rIF.getImaginaryArray(); - - if (! v || nx == 0 || ny == 0) - return false; - - Array2d adView (nx, ny); - Array2d adDet (nx, ny); - double** ppdView = adView.getArray(); - double** ppdDet = adDet.getArray(); - - std::complex** ppcDetValue = new std::complex* [m_nView]; - unsigned int iView; - double* pdDet = new double [m_nDet]; - fftw_complex* pcIn = new fftw_complex [m_nDet]; - fftw_plan plan = fftw_create_plan (m_nDet, FFTW_FORWARD, FFTW_IN_PLACE); - - for (iView = 0; iView < m_nView; iView++) { - ppcDetValue[iView] = new std::complex [m_nDet]; - unsigned int iDet; - for (iDet = 0; iDet < m_nDet; iDet++) { - pcIn[iDet].re = getDetectorArray(iView).detValues()[iDet]; - pcIn[iDet].im = 0; - } - fftw_one (plan, pcIn, NULL); - for (iDet = 0; iDet < m_nDet; iDet++) - ppcDetValue[iView][iDet] = std::complex (pcIn[iDet].re, pcIn[iDet].im); - Fourier::shuffleFourierToNaturalOrder (ppcDetValue[iView], m_nDet); - } - - fftw_destroy_plan (plan); - - delete [] pcIn; - - calcArrayPolarCoordinates (nx, ny, ppdView, ppdDet); - - interpolatePolar (v, vImag, nx, ny, ppcDetValue, ppdView, ppdDet, m_nView, m_nDet, iInterpolationID); - - for (iView = 0; iView < m_nView; iView++) - delete [] ppcDetValue[iView]; - delete [] ppcDetValue; - - return true; -} - - diff --git a/msvc/ctsim/ctsim.dsp b/msvc/ctsim/ctsim.dsp index c5c3ddf..98de617 100644 --- a/msvc/ctsim/ctsim.dsp +++ b/msvc/ctsim/ctsim.dsp @@ -165,11 +165,6 @@ SOURCE=..\..\..\wx2\include\wx\msw\wx\msw\bullseye.cur # End Source File # Begin Source File -SOURCE=.\ctsim.rc -# PROP Exclude_From_Build 1 -# End Source File -# Begin Source File - SOURCE=.\wx\msw\error.ico # End Source File # Begin Source File @@ -296,6 +291,10 @@ SOURCE=.\wx\msw\watch1.cur SOURCE=..\..\..\wx2\include\wx\msw\wx\msw\watch1.cur # End Source File +# Begin Source File + +SOURCE=..\..\..\wx2\include\wx\msw\wx.rc +# End Source File # End Group # End Target # End Project diff --git a/msvc/ctsim/ctsim.plg b/msvc/ctsim/ctsim.plg index 5ff72f1..526600d 100644 --- a/msvc/ctsim/ctsim.plg +++ b/msvc/ctsim/ctsim.plg @@ -6,13 +6,13 @@ --------------------Configuration: ctsim - Win32 Debug--------------------

Command Lines

-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1A0.tmp" with contents +Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP12.tmp" with contents [ /nologo /G6 /MTd /W3 /Gm /GR /GX /ZI /Od /I "\wx2\include" /I "." /I "..\..\include" /I "..\..\getopt" /I "..\..\..\lpng108" /I "..\..\..\zlib" /I "..\..\..\fftw-2.1.3\fftw" /I "..\..\..\fftw-2.1.3\rfftw" /D VERSION=\"2.5.0\" /D "_DEBUG" /D "__WXMSW__" /D "HAVE_SGP" /D "HAVE_PNG" /D "HAVE_WXWINDOWS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "HAVE_STRING_H" /D "HAVE_FFTW" /D "HAVE_RFFTW" /D "HAVE_GETOPT_H" /D "MSVC" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D CTSIMVERSION=\"3.0.0beta1\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c -"C:\ctsim\src\dialogs.cpp" +"C:\ctsim\src\views.cpp" ] -Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1A0.tmp" -Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1A1.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP12.tmp" +Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP13.tmp" with contents [ comctl32.lib winmm.lib rpcrt4.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ../libctsim/Debug/libctsim.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\lpng108\msvc\win32\libpng\lib_dbg\libpng.lib ..\..\..\lpng108\msvc\win32\zlib\lib_dbg\zlib.lib libcmtd.lib ..\..\..\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib ..\..\..\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib ../../../wx2/lib/wxd.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrtd.lib" /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"..\..\..\lpng108\msvc\win32\libpng\lib" /libpath:"..\..\..\lpng108\msvc\win32\zlib\lib" .\Debug\ctsim.obj @@ -27,20 +27,16 @@ comctl32.lib winmm.lib rpcrt4.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib w "\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib" \wx2\lib\wxd.lib ] -Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1A1.tmp" +Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP13.tmp"

Output Window

Compiling... -dialogs.cpp +views.cpp Linking... -Creating command line "bscmake.exe /nologo /o"Debug/ctsim.bsc" .\Debug\ctsim.sbr .\Debug\dialogs.sbr .\Debug\dlgprojections.sbr .\Debug\dlgreconstruct.sbr .\Debug\docs.sbr .\Debug\views.sbr" -Creating browse info file... -BSCMAKE: warning BK4503 : minor error in .SBR file '.\Debug\dialogs.sbr' ignored -

Output Window

Results

-ctsim.exe - 0 error(s), 1 warning(s) +ctsim.exe - 0 error(s), 0 warning(s) diff --git a/src/ctsim.cpp b/src/ctsim.cpp index fb835ad..b8a1154 100644 --- a/src/ctsim.cpp +++ b/src/ctsim.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: ctsim.cpp,v 1.25 2001/01/02 16:02:13 kevin Exp $ +** $Id: ctsim.cpp,v 1.26 2001/01/06 15:33:15 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 @@ -61,7 +61,7 @@ #endif #endif -static const char* rcsindent = "$Id: ctsim.cpp,v 1.25 2001/01/02 16:02:13 kevin Exp $"; +static const char* rcsindent = "$Id: ctsim.cpp,v 1.26 2001/01/06 15:33:15 kevin Exp $"; class CTSimApp* theApp = NULL; @@ -132,7 +132,7 @@ CTSimApp::OnInit() //// Create the main frame window m_pFrame = new MainFrame(m_docManager, (wxFrame *) NULL, -1, "CTSim", wxPoint(0, 0), wxSize(500, 400), wxDEFAULT_FRAME_STYLE); - + SetTopWindow (m_pFrame); m_pFrame->Centre(wxBOTH); @@ -180,9 +180,16 @@ CTSimApp::getUntitledFilename() // Top-level window for CTSim +#if CTSIM_MDI +IMPLEMENT_CLASS(MainFrame, wxMDIParentFrame) + +BEGIN_EVENT_TABLE(MainFrame, wxMDIParentFrame) +#else IMPLEMENT_CLASS(MainFrame, wxDocParentFrame) BEGIN_EVENT_TABLE(MainFrame, wxDocParentFrame) +#endif + EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout) EVT_MENU(MAINMENU_HELP_CONTENTS, MainFrame::OnHelpContents) EVT_MENU(MAINMENU_FILE_CREATE_PHANTOM, MainFrame::OnCreatePhantom) @@ -213,8 +220,13 @@ END_EVENT_TABLE() +#if CTSIM_MDI +MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type) +: wxMDIParentFrame(NULL, id, title, pos, size, type), m_pLog(NULL) +#else MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type) : wxDocParentFrame(manager, frame, id, title, pos, size, type), m_pLog(NULL) +#endif { m_pLog = new wxTextCtrl (this, -1, "Log Window\n", wxPoint(0, 250), wxSize(100,50), wxTE_MULTILINE | wxTE_READONLY); wxLog::SetActiveTarget(new wxLogTextCtrl(m_pLog)); @@ -232,7 +244,7 @@ MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const file_menu->Append(MAINMENU_FILE_EXIT, "E&xit"); // history of files visited - m_docManager->FileHistoryUseMenu(file_menu); + theApp->getDocManager()->FileHistoryUseMenu(file_menu); m_pWindowMenu = new wxMenu; m_pWindowMenu->UpdateUI (this); @@ -372,7 +384,7 @@ void MainFrame::OnUpdateUI (wxUpdateUIEvent& rEvent) { int iPos = 0; - wxList& rListDocs = m_docManager->GetDocuments(); + wxList& rListDocs = theApp->getDocManager()->GetDocuments(); wxNode* pNode = rListDocs.GetFirst(); while (iPos < MAX_WINDOW_MENUITEMS && pNode != NULL) { wxDocument* pDoc = static_cast(pNode->GetData()); diff --git a/src/ctsim.h b/src/ctsim.h index e1055ba..9093b9b 100644 --- a/src/ctsim.h +++ b/src/ctsim.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: ctsim.h,v 1.21 2001/01/04 21:28:41 kevin Exp $ +** $Id: ctsim.h,v 1.22 2001/01/06 15:33:15 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 @@ -35,6 +35,11 @@ #include #endif +#ifdef MSVC +// #define CTSIM_MDI 1 +#endif + + class wxMenu; class wxDocument; @@ -47,7 +52,11 @@ class ImageFileDocument; // Define a new frame for main window +#if CTSIM_MDI +class MainFrame: public wxMDIParentFrame +#else class MainFrame: public wxDocParentFrame +#endif { DECLARE_CLASS(MainFrame) private: @@ -156,14 +165,13 @@ extern class CTSimApp* theApp; enum { MAINMENU_HELP_ABOUT = 500, + MAINMENU_WINDOW_BASE, MAINMENU_HELP_CONTENTS, MAINMENU_FILE_CREATE_PHANTOM, MAINMENU_FILE_CREATE_FILTER, MAINMENU_FILE_EXIT, - IFMENU_FILE_PROPERTIES, - PJMENU_FILE_PROPERTIES, PJMENU_RECONSTRUCT_FBP, PJMENU_RECONSTRUCT_FOURIER, @@ -171,9 +179,12 @@ enum { PJMENU_CONVERT_FFT_POLAR, IFMENU_FILE_EXPORT, + IFMENU_FILE_PROPERTIES, IFMENU_PLOT_ROW, IFMENU_PLOT_COL, + IFMENU_PLOT_FFT_ROW, + IFMENU_PLOT_FFT_COL, IFMENU_PLOT_HISTOGRAM, IFMENU_VIEW_SCALE_AUTO, @@ -198,6 +209,10 @@ enum { IFMENU_FILTER_INVERSE_FOURIER, IFMENU_FILTER_FFT, IFMENU_FILTER_IFFT, + IFMENU_FILTER_FFT_ROWS, + IFMENU_FILTER_FFT_COLS, + IFMENU_FILTER_IFFT_ROWS, + IFMENU_FILTER_IFFT_COLS, IFMENU_FILTER_MAGNITUDE, IFMENU_FILTER_PHASE, IFMENU_FILTER_SHUFFLENATURALTOFOURIERORDER, @@ -210,7 +225,7 @@ enum { PLOTMENU_VIEW_SCALE_MINMAX, PLOTMENU_VIEW_SCALE_AUTO, PLOTMENU_VIEW_SCALE_FULL, - MAINMENU_WINDOW_BASE, + }; #endif diff --git a/src/docs.cpp b/src/docs.cpp index d9b3d10..e458a02 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: docs.cpp,v 1.11 2001/01/02 16:02:13 kevin Exp $ +** $Id: docs.cpp,v 1.12 2001/01/06 15:33:15 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 @@ -132,6 +132,7 @@ bool ProjectionFileDocument::OnOpenDocument(const wxString& filename) } Modify(false); UpdateAllViews(); + GetFirstView()->OnUpdate (GetFirstView(), NULL); return true; } @@ -176,6 +177,7 @@ bool PhantomDocument::OnOpenDocument(const wxString& filename) m_idPhantom = m_phantom.id(); Modify(false); UpdateAllViews(); + GetFirstView()->OnUpdate (GetFirstView(), NULL); return true; } diff --git a/src/views.cpp b/src/views.cpp index aba89cc..7c47aa6 100644 --- a/src/views.cpp +++ b/src/views.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: views.cpp,v 1.51 2001/01/04 21:28:41 kevin Exp $ +** $Id: views.cpp,v 1.52 2001/01/06 15:33:15 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 @@ -188,14 +188,22 @@ EVT_MENU(IFMENU_IMAGE_SUBTRACT, ImageFileView::OnSubtract) EVT_MENU(IFMENU_IMAGE_MULTIPLY, ImageFileView::OnMultiply) EVT_MENU(IFMENU_IMAGE_DIVIDE, ImageFileView::OnDivide) EVT_MENU(IFMENU_IMAGE_SCALESIZE, ImageFileView::OnScaleSize) -#ifdef HAVE_FFTW +#ifdef HAVE_FFT EVT_MENU(IFMENU_FILTER_FFT, ImageFileView::OnFFT) EVT_MENU(IFMENU_FILTER_IFFT, ImageFileView::OnIFFT) +EVT_MENU(IFMENU_FILTER_FFT_ROWS, ImageFileView::OnFFTRows) +EVT_MENU(IFMENU_FILTER_IFFT_ROWS, ImageFileView::OnIFFTRows) +EVT_MENU(IFMENU_FILTER_FFT_COLS, ImageFileView::OnFFTCols) +EVT_MENU(IFMENU_FILTER_IFFT_COLS, ImageFileView::OnIFFTCols) #endif EVT_MENU(IFMENU_FILTER_MAGNITUDE, ImageFileView::OnMagnitude) EVT_MENU(IFMENU_FILTER_PHASE, ImageFileView::OnPhase) EVT_MENU(IFMENU_PLOT_ROW, ImageFileView::OnPlotRow) EVT_MENU(IFMENU_PLOT_COL, ImageFileView::OnPlotCol) +#ifdef HAVE_FFT +EVT_MENU(IFMENU_PLOT_FFT_ROW, ImageFileView::OnPlotFFTRow) +EVT_MENU(IFMENU_PLOT_FFT_COL, ImageFileView::OnPlotFFTCol) +#endif EVT_MENU(IFMENU_PLOT_HISTOGRAM, ImageFileView::OnPlotHistogram) END_EVENT_TABLE() @@ -577,7 +585,6 @@ void ImageFileView::OnFFT (wxCommandEvent& event) { ImageFile& rIF = GetDocument()->getImageFile(); - wxProgressDialog dlgProgress (wxString("FFT"), wxString("FFT Progress"), 1, m_frame, wxPD_APP_MODAL); rIF.fft (rIF); rIF.labelAdd ("FFT Image"); m_bMinSpecified = false; @@ -591,7 +598,6 @@ void ImageFileView::OnIFFT (wxCommandEvent& event) { ImageFile& rIF = GetDocument()->getImageFile(); - wxProgressDialog dlgProgress (wxString("IFFT"), wxString("IFFT Progress"), 1, m_frame, wxPD_APP_MODAL); rIF.ifft (rIF); rIF.labelAdd ("IFFT Image"); m_bMinSpecified = false; @@ -600,6 +606,58 @@ ImageFileView::OnIFFT (wxCommandEvent& event) GetDocument()->Modify(TRUE); GetDocument()->UpdateAllViews(this); } + +void +ImageFileView::OnFFTRows (wxCommandEvent& event) +{ + ImageFile& rIF = GetDocument()->getImageFile(); + rIF.fftRows (rIF); + rIF.labelAdd ("FFT Rows"); + m_bMinSpecified = false; + m_bMaxSpecified = false; + if (theApp->getSetModifyNewDocs()) + GetDocument()->Modify(TRUE); + GetDocument()->UpdateAllViews(this); +} + +void +ImageFileView::OnIFFTRows (wxCommandEvent& event) +{ + ImageFile& rIF = GetDocument()->getImageFile(); + rIF.ifftRows (rIF); + rIF.labelAdd ("IFFT Rows"); + m_bMinSpecified = false; + m_bMaxSpecified = false; + if (theApp->getSetModifyNewDocs()) + GetDocument()->Modify(TRUE); + GetDocument()->UpdateAllViews(this); +} + +void +ImageFileView::OnFFTCols (wxCommandEvent& event) +{ + ImageFile& rIF = GetDocument()->getImageFile(); + rIF.fftCols (rIF); + rIF.labelAdd ("FFT Columns"); + m_bMinSpecified = false; + m_bMaxSpecified = false; + if (theApp->getSetModifyNewDocs()) + GetDocument()->Modify(TRUE); + GetDocument()->UpdateAllViews(this); +} + +void +ImageFileView::OnIFFTCols (wxCommandEvent& event) +{ + ImageFile& rIF = GetDocument()->getImageFile(); + rIF.ifftCols (rIF); + rIF.labelAdd ("IFFT Columns"); + m_bMinSpecified = false; + m_bMaxSpecified = false; + if (theApp->getSetModifyNewDocs()) + GetDocument()->Modify(TRUE); + GetDocument()->UpdateAllViews(this); +} #endif void @@ -706,7 +764,11 @@ ImageFileView::CreateCanvas (wxView *view, wxFrame *parent) wxFrame* ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view) { +#if CTSIM_MDI + wxMDIChildFrame *subframe = new wxMDIChildFrame(theApp->getMainFrame(), -1, "ImageFile Frame", wxPoint(-1, -1), wxSize(0, 0), wxDEFAULT_FRAME_STYLE); +#else wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "ImageFile Frame", wxPoint(-1, -1), wxSize(0, 0), wxDEFAULT_FRAME_STYLE); +#endif wxMenu *file_menu = new wxMenu; @@ -739,8 +801,12 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view) filter_menu->Append (IFMENU_FILTER_EXP, "&Exp"); filter_menu->AppendSeparator(); #ifdef HAVE_FFT - filter_menu->Append (IFMENU_FILTER_FFT, "&FFT"); - filter_menu->Append (IFMENU_FILTER_IFFT, "&IFFT"); + filter_menu->Append (IFMENU_FILTER_FFT, "2D &FFT"); + filter_menu->Append (IFMENU_FILTER_IFFT, "2D &IFFT"); + filter_menu->Append (IFMENU_FILTER_FFT_ROWS, "FFT Rows"); + filter_menu->Append (IFMENU_FILTER_IFFT_ROWS, "IFFT Rows"); + filter_menu->Append (IFMENU_FILTER_FFT_COLS, "FFT Columns"); + filter_menu->Append (IFMENU_FILTER_IFFT_COLS, "IFFT Columns"); filter_menu->Append (IFMENU_FILTER_FOURIER, "F&ourier"); filter_menu->Append (IFMENU_FILTER_INVERSE_FOURIER, "Inverse Fo&urier"); #else @@ -765,6 +831,9 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view) analyze_menu->Append (IFMENU_PLOT_COL, "Plot &Column"); analyze_menu->Append (IFMENU_PLOT_HISTOGRAM, "Plot &Histogram"); analyze_menu->AppendSeparator(); + analyze_menu->Append (IFMENU_PLOT_FFT_ROW, "Plot FFT Row"); + analyze_menu->Append (IFMENU_PLOT_FFT_COL, "Plot FFT Column"); + analyze_menu->AppendSeparator(); analyze_menu->Append (IFMENU_COMPARE_IMAGES, "Compare &Images..."); analyze_menu->Append (IFMENU_COMPARE_ROW, "Compare &Row"); analyze_menu->Append (IFMENU_COMPARE_COL, "Compare &Column"); @@ -876,7 +945,7 @@ ImageFileView::OnClose (bool deleteWindow) if (!GetDocument()->Close()) return false; - m_canvas->Clear(); + // m_canvas->Clear(); m_canvas->m_pView = NULL; m_canvas = NULL; wxString s(theApp->GetAppName()); @@ -958,6 +1027,7 @@ ImageFileView::OnScaleSize (wxCommandEvent& event) } ImageFile& rScaledIF = pScaledDoc->getImageFile(); rScaledIF.setArraySize (iNewNX, iNewNY); + rScaledIF.labelsCopy (rIF); rScaledIF.labelAdd (os.str().c_str()); rIF.scaleImage (rScaledIF); *theApp->getLog() << os.str().c_str() << "\n"; @@ -1064,6 +1134,142 @@ ImageFileView::OnPlotCol (wxCommandEvent& event) } } +#ifdef HAVE_FFT +void +ImageFileView::OnPlotFFTRow (wxCommandEvent& event) +{ + int xCursor, yCursor; + if (! m_canvas->GetCurrentCursor (xCursor, yCursor)) { + wxMessageBox ("No row selected. Please use left mouse button on image to select column","Error"); + return; + } + + const ImageFile& rIF = dynamic_cast(GetDocument())->getImageFile(); + ImageFileArrayConst v = rIF.getArray(); + ImageFileArrayConst vImag = rIF.getImaginaryArray(); + int nx = rIF.nx(); + int ny = rIF.ny(); + + if (v != NULL && yCursor < ny) { + fftw_complex* pcIn = new fftw_complex [nx]; + + int i; + for (i = 0; i < nx; i++) { + pcIn[i].re = v[i][yCursor]; + if (rIF.isComplex()) + pcIn[i].im = vImag[i][yCursor]; + else + pcIn[i].im = 0; + } + + fftw_plan plan = fftw_create_plan (nx, FFTW_FORWARD, FFTW_IN_PLACE); + fftw_one (plan, pcIn, NULL); + fftw_destroy_plan (plan); + + double* pX = new double [nx]; + double* pYReal = new double [nx]; + double* pYImag = new double [nx]; + double* pYMag = new double [nx]; + for (i = 0; i < nx; i++) { + pX[i] = i; + pYReal[i] = pcIn[i].re; + pYImag[i] = pcIn[i].im; + pYMag[i] = ::sqrt (pcIn[i].re * pcIn[i].re + pcIn[i].im * pcIn[i].im); + } + Fourier::shuffleFourierToNaturalOrder (pYReal, nx); + Fourier::shuffleFourierToNaturalOrder (pYImag, nx); + Fourier::shuffleFourierToNaturalOrder (pYMag, nx); + + PlotFileDocument* pPlotDoc = dynamic_cast(theApp->getDocManager()->CreateDocument("untitled.plt", wxDOC_SILENT)); + if (! pPlotDoc) { + sys_error (ERR_SEVERE, "Internal error: unable to create Plot file"); + } else { + PlotFile& rPlotFile = pPlotDoc->getPlotFile(); + std::ostringstream os; + os << "Row " << yCursor; + std::string title("title "); + title += os.str(); + rPlotFile.addEzsetCommand (title.c_str()); + rPlotFile.addEzsetCommand ("xlabel Column"); + rPlotFile.addEzsetCommand ("ylabel Pixel Value"); + rPlotFile.addEzsetCommand ("lxfrac 0"); + rPlotFile.addEzsetCommand ("curve 1"); + rPlotFile.addEzsetCommand ("color 1"); + rPlotFile.addEzsetCommand ("curve 2"); + rPlotFile.addEzsetCommand ("color 2"); + rPlotFile.addEzsetCommand ("dash 1"); + rPlotFile.addEzsetCommand ("curve 3"); + rPlotFile.addEzsetCommand ("dash 2"); + rPlotFile.addEzsetCommand ("color 3"); + rPlotFile.addEzsetCommand ("box"); + rPlotFile.addEzsetCommand ("grid"); + rPlotFile.setCurveSize (2, nx); + rPlotFile.addColumn (0, pX); + rPlotFile.addColumn (1, pYReal); + rPlotFile.addColumn (2, pYImag); + rPlotFile.addColumn (3, pYMag); + } + delete pX; + delete pYReal; + delete pYImag; + delete pYMag; + delete [] pcIn; + + if (theApp->getSetModifyNewDocs()) + pPlotDoc->Modify(true); + pPlotDoc->UpdateAllViews(); + } +} + +void +ImageFileView::OnPlotFFTCol (wxCommandEvent& event) +{ + int xCursor, yCursor; + if (! m_canvas->GetCurrentCursor (xCursor, yCursor)) { + wxMessageBox ("No column selected. Please use left mouse button on image to select column","Error"); + return; + } + + const ImageFile& rIF = dynamic_cast(GetDocument())->getImageFile(); + ImageFileArrayConst v = rIF.getArray(); + int nx = rIF.nx(); + int ny = rIF.ny(); + + if (v != NULL && xCursor < nx) { + double* pX = new double [ny]; + double* pY = new double [ny]; + for (int i = 0; i < ny; i++) { + pX[i] = i; + pY[i] = v[xCursor][i]; + } + PlotFileDocument* pPlotDoc = dynamic_cast(theApp->getDocManager()->CreateDocument("untitled.plt", wxDOC_SILENT)); + if (! pPlotDoc) { + sys_error (ERR_SEVERE, "Internal error: unable to create Plot file"); + } else { + PlotFile& rPlotFile = pPlotDoc->getPlotFile(); + std::ostringstream os; + os << "Column " << xCursor; + std::string title("title "); + title += os.str(); + rPlotFile.addEzsetCommand (title.c_str()); + rPlotFile.addEzsetCommand ("xlabel Row"); + rPlotFile.addEzsetCommand ("ylabel Pixel Value"); + rPlotFile.addEzsetCommand ("lxfrac 0"); + rPlotFile.addEzsetCommand ("box"); + rPlotFile.addEzsetCommand ("grid"); + rPlotFile.setCurveSize (2, nx); + rPlotFile.addColumn (0, pX); + rPlotFile.addColumn (1, pY); + } + delete pX; + delete pY; + if (theApp->getSetModifyNewDocs()) + pPlotDoc->Modify(true); + pPlotDoc->UpdateAllViews(); + } +} +#endif + void ImageFileView::OnCompareCol (wxCommandEvent& event) { @@ -1301,6 +1507,10 @@ PhantomView::PhantomView(void) m_dDefaultFieldOfView = 1; m_iDefaultGeometry = Scanner::GEOMETRY_PARALLEL; m_iDefaultTrace = Trace::TRACE_NONE; + + m_iDefaultRasterNX = 256; + m_iDefaultRasterNY = 256; + m_iDefaultRasterNSamples = 2; } PhantomView::~PhantomView(void) @@ -1416,15 +1626,15 @@ PhantomView::OnProjections (wxCommandEvent& event) void PhantomView::OnRasterize (wxCommandEvent& event) { - DialogGetRasterParameters dialogRaster (m_frame, 256, 256, 1); + DialogGetRasterParameters dialogRaster (m_frame, m_iDefaultRasterNX, m_iDefaultRasterNY, m_iDefaultRasterNSamples); int retVal = dialogRaster.ShowModal(); if (retVal == wxID_OK) { - int xSize = dialogRaster.getXSize(); - int ySize = dialogRaster.getYSize(); - int nSamples = dialogRaster.getNSamples(); - if (nSamples < 1) - nSamples = 1; - if (xSize > 0 && ySize > 0) { + m_iDefaultRasterNX = dialogRaster.getXSize(); + m_iDefaultRasterNY = dialogRaster.getYSize(); + m_iDefaultRasterNSamples = dialogRaster.getNSamples(); + if (m_iDefaultRasterNSamples < 1) + m_iDefaultRasterNSamples = 1; + if (m_iDefaultRasterNX > 0 && m_iDefaultRasterNY > 0) { const Phantom& rPhantom = GetDocument()->getPhantom(); ImageFileDocument* pRasterDoc = dynamic_cast(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT)); if (! pRasterDoc) { @@ -1433,11 +1643,11 @@ PhantomView::OnRasterize (wxCommandEvent& event) } ImageFile& imageFile = pRasterDoc->getImageFile(); - imageFile.setArraySize (xSize, ySize); + imageFile.setArraySize (m_iDefaultRasterNX, m_iDefaultRasterNX); wxProgressDialog dlgProgress (wxString("Rasterize"), wxString("Rasterization Progress"), imageFile.nx() + 1, m_frame, wxPD_CAN_ABORT); Timer timer; for (unsigned int i = 0; i < imageFile.nx(); i++) { - rPhantom.convertToImagefile (imageFile, nSamples, Trace::TRACE_NONE, i, 1, true); + rPhantom.convertToImagefile (imageFile, m_iDefaultRasterNSamples, Trace::TRACE_NONE, i, 1, true); if (! dlgProgress.Update(i+1)) { pRasterDoc->DeleteAllViews(); return; @@ -1447,7 +1657,8 @@ PhantomView::OnRasterize (wxCommandEvent& event) pRasterDoc->Modify(true); pRasterDoc->UpdateAllViews(this); std::ostringstream os; - os << "Rasterize Phantom " << rPhantom.name() << ": XSize=" << xSize << ", YSize=" << ySize << ", nSamples=" << nSamples; + os << "Rasterize Phantom " << rPhantom.name() << ": XSize=" << m_iDefaultRasterNX << ", YSize=" + << m_iDefaultRasterNY << ", nSamples=" << m_iDefaultRasterNSamples; *theApp->getLog() << os.str().c_str() << "\n"; imageFile.labelAdd (os.str().c_str(), timer.timerEnd()); ImageFileView* rasterView = dynamic_cast(pRasterDoc->GetFirstView()); @@ -1479,8 +1690,12 @@ PhantomView::CreateCanvas (wxView *view, wxFrame *parent) wxFrame* PhantomView::CreateChildFrame(wxDocument *doc, wxView *view) { +#if CTSIM_MDI + wxMDIChildFrame *subframe = new wxMDIChildFrame(theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(256, 256), wxDEFAULT_FRAME_STYLE); +#else wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(256, 256), wxDEFAULT_FRAME_STYLE); - +#endif + wxMenu *file_menu = new wxMenu; file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom..."); @@ -1556,17 +1771,18 @@ PhantomView::OnClose (bool deleteWindow) if (!GetDocument()->Close()) return false; - m_canvas->Clear(); +// m_canvas->Clear(); m_canvas->m_pView = NULL; m_canvas = NULL; - wxString s(wxTheApp->GetAppName()); - if (m_frame) - m_frame->SetTitle(s); +// wxString s(wxTheApp->GetAppName()); +// if (m_frame) +// m_frame->SetTitle(s); SetFrame(NULL); Activate(false); if (deleteWindow) { + delete m_frame; return true; } @@ -1834,8 +2050,12 @@ ProjectionFileView::CreateCanvas (wxView *view, wxFrame *parent) wxFrame* ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view) { +#ifdef CTSIM_MDI + wxMDIChildFrame *subframe = new wxMDIChildFrame (theApp->getMainFrame(), -1, "Projection Frame", wxPoint(10, 10), wxSize(0, 0), wxDEFAULT_FRAME_STYLE); +#else wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Projection Frame", wxPoint(10, 10), wxSize(0, 0), wxDEFAULT_FRAME_STYLE); - +#endif + wxMenu *file_menu = new wxMenu; file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom..."); @@ -1967,7 +2187,7 @@ ProjectionFileView::OnClose (bool deleteWindow) if (!GetDocument()->Close()) return false; - m_canvas->Clear(); + // m_canvas->Clear(); m_canvas->m_pView = NULL; m_canvas = NULL; wxString s(wxTheApp->GetAppName()); @@ -2118,8 +2338,12 @@ PlotFileView::CreateCanvas (wxView *view, wxFrame *parent) wxFrame* PlotFileView::CreateChildFrame(wxDocument *doc, wxView *view) { +#ifdef CTSIM_MDI + wxMDIChildFrame *subframe = new wxMDIChildFrame (theApp->getMainFrame(), -1, "Plot Frame", wxPoint(10, 10), wxSize(500, 300), wxDEFAULT_FRAME_STYLE); +#else wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Plot Frame", wxPoint(10, 10), wxSize(500, 300), wxDEFAULT_FRAME_STYLE); - +#endif + wxMenu *file_menu = new wxMenu; file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom..."); @@ -2259,7 +2483,7 @@ PlotFileView::OnClose (bool deleteWindow) if (!GetDocument()->Close()) return false; - m_canvas->Clear(); + // m_canvas->Clear(); m_canvas->m_pView = NULL; m_canvas = NULL; wxString s(wxTheApp->GetAppName()); diff --git a/src/views.h b/src/views.h index 7ca2e62..eee1be8 100644 --- a/src/views.h +++ b/src/views.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: views.h,v 1.25 2001/01/04 21:28:41 kevin Exp $ +** $Id: views.h,v 1.26 2001/01/06 15:33:15 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 @@ -90,6 +90,10 @@ public: #ifdef HAVE_FFT void OnFFT (wxCommandEvent& event); void OnIFFT (wxCommandEvent& event); + void OnFFTRows (wxCommandEvent& event); + void OnIFFTRows (wxCommandEvent& event); + void OnFFTCols (wxCommandEvent& event); + void OnIFFTCols (wxCommandEvent& event); #endif void OnMagnitude (wxCommandEvent& event); @@ -100,6 +104,10 @@ public: void OnScaleFull (wxCommandEvent& event); void OnPlotRow (wxCommandEvent& event); void OnPlotCol (wxCommandEvent& event); +#if HAVE_FFT + void OnPlotFFTRow (wxCommandEvent& event); + void OnPlotFFTCol (wxCommandEvent& event); +#endif void OnPlotHistogram (wxCommandEvent& event); void OnCompareRow (wxCommandEvent& event); void OnCompareCol (wxCommandEvent& event); @@ -218,6 +226,10 @@ private: double m_dDefaultFocalLength; double m_dDefaultFieldOfView; + int m_iDefaultRasterNX; + int m_iDefaultRasterNY; + int m_iDefaultRasterNSamples; + public: PhantomView(void); virtual ~PhantomView(void); -- 2.34.1