-2.0.0-b4 - 7/11/00
+2.0.0-b4 - 7/13/00
Fixed compiler warnings at -Wall level
Began work on CTSim program to be graphical front-end of all functions
Moved current src/*.cpp to tools/*.cpp
not work.
fftw (http://www.fftw.org)
- Fastest Fourier Transform in the West
+ Fastest Fourier Transform in the West. Currently, the only FFT
+ routines used by CTSim.
+
+wxWindows (http://www.wxwindows.org)
+ Used by CTSim (src/*) graphic front-end
+
+g2 (http://g2.sourceforge.net)
+ Currently, used partially by SGP (Simple Graphics Package) for
+graphical display by command-line tools (tools/*). This library
+will likely be deprecated in favor of wxWindows.
lam (http://www.mpi.nd.edu/lam/)
There is support is MPI clustering. I use this code at home for my
-6/17/2000
- CTSim converted to C++ and has cross-platform compatible data files.
+Version 2.0 of CTSim is near completion!
+
+
+New Features of CTSim version 2.0:
+
+- Entire code-base, except for SGP & EZPlot, cleaned up and
+ re-written. All code converted to C++.
+
+- Integrated G2 library for graphical display from command line tools
+
+- Graphic front-end (ctsim) initial implemention. Can display
+ projection and image files.
+
+- Added frequency-based filtering. Can provide significant speed-up
+ in reconstructions compared to convolution-based filtering.
+
+- Added highly-optimized backprojection method (idiff3)
+
+- New command-line tools added for image statistics and comparisons with
+ both text and graphical outputs.
MISCELLANEOUS
=============
-Integrate low-level X11 graphics, replace all low-level driver code in
-libgraph. All the high-level graphics routines are in place.
+Convert SGP graphics to wxWindows.
-PROPOSED MENU STRUCTURE
-=======================
-File
- New
- Phantom
- Open
- SDF
-
-Process
- Simulate CT process (active only when phantom outline shown)
- Rasterize Phantom (active only when phantom outline shown)
- Reconstruct CT data (active only when raysum data is shown)
-
-Filter
- (Various single and dual image transformations)
-
-Compare
- Compare 2 images
- 2D grayscale subtraction
- 1D column plots
- Single Image statistics
-
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ezplot.h,v 1.8 2000/06/20 17:54:51 kevin Exp $
+** $Id: ezplot.h,v 1.9 2000/07/15 08:36:13 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
/* ezplot.cpp */
-SGP_ID ezplot(float x[], double y[], int num);
-SGP_ID ezplot(double x[], double y[], int num);
+SGP_ID ezplot (const float x[], const double y[], int num);
+SGP_ID ezplot (const double x[], const double y[], int num);
void ezinit(void);
void ezfree(void);
void ezclear(void);
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: phantom.h,v 1.5 2000/07/13 07:03:21 kevin Exp $
+** $Id: phantom.h,v 1.6 2000/07/15 08:36:13 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
static int numCirclePoints (double theta);
+ PhantomElement (const PhantomElement& rhs); // copy constructor
+ PhantomElement& operator= (const PhantomElement&); // assignment operator
};
static const char* convertPhantomIDToName (const PhantomID phmID);
void init(void);
+
+ Phantom (const Phantom& rhs); // copy constructor
+ Phantom& operator= (const Phantom&); // assignment operator
};
typedef slist<PhantomElement*>::iterator PElemIterator;
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: projections.h,v 1.9 2000/07/13 07:03:21 kevin Exp $
+** $Id: projections.h,v 1.10 2000/07/15 08:36:13 kevin Exp $
**
**
** This program is free software; you can redistribute it and/or modify
bool detarrayRead (fnetorderstream& fs, DetectorArray& darray, const int view_num);
bool detarrayWrite (fnetorderstream& fs, const DetectorArray& darray, const int view_num);
- bool reconstruct (ImageFile& im, const char* const filterName, double filt_param, const char* const filterMethodName, const int zeropad, const char* const interpName, int interp_param, const char* const backprojName, const int trace);
+ bool reconstruct (ImageFile& im, const char* const filterName, double filt_param, const char* const filterMethodName, const int zeropad, const char* const interpName, int interp_param, const char* const backprojName, const int trace) const;
void setNView (int nView); // used in MPI to restrict # of views
void setRotInc (double rotInc) { m_rotInc = rotInc;}
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ezplot.cpp,v 1.5 2000/07/13 07:03:21 kevin Exp $
+** $Id: ezplot.cpp,v 1.6 2000/07/15 08:36:13 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
SGP_ID
-ezplot (float x[], double y[], int num)
+ezplot (const float x[], const double y[], int num)
{
double dx [num];
SGP_ID
-ezplot (double x[], double y[], int num)
+ezplot (const double x[], const double y[], int num)
{
unsigned int size;
SGP_ID gid = NULL;
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: filter.cpp,v 1.17 2000/07/13 07:03:21 kevin Exp $
+** $Id: filter.cpp,v 1.18 2000/07/15 08:36:13 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
#endif
}
- if (m_idFilterMethod == FILTER_METHOD_FOURIER || FILTER_METHOD_FOURIER_TABLE || m_idFilterMethod == FILTER_METHOD_FFT
+ if (m_idFilterMethod == FILTER_METHOD_FOURIER || m_idFilterMethod == FILTER_METHOD_FOURIER_TABLE || m_idFilterMethod == FILTER_METHOD_FFT
#if HAVE_FFTW
|| m_idFilterMethod == FILTER_METHOD_FFTW || m_idFilterMethod == FILTER_METHOD_RFFTW
#endif
nextPowerOf2++;
nextPowerOf2 += (m_zeropad - 1);
m_nFilterPoints = 1 << nextPowerOf2;
- cout << "nFilterPoints = " << m_nFilterPoints << endl;
+ if (m_traceLevel >= TRACE_TEXT)
+ cout << "nFilterPoints = " << m_nFilterPoints << endl;
}
m_nOutputPoints = m_nFilterPoints * m_preinterpolationFactor;
m_filterMin = -1. / (2 * m_signalInc);
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: imagefile.cpp,v 1.8 2000/07/13 07:03:21 kevin Exp $
+** $Id: imagefile.cpp,v 1.9 2000/07/15 08:36:13 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
int
ImageFile::displayScaling (const int scale, const ImageFileValue pmin, const ImageFileValue pmax) const
{
- int grayscale[256];
int nx = m_nx;
int ny = m_ny;
ImageFileArrayConst v = getArray();
double view_scale = 255 / (pmax - pmin);
int id_X11 = g2_open_X11 (nx * scale, ny * scale);
-
+ int grayscale[256];
for (int i = 0; i < 256; i++) {
double cval = i / 255.;
grayscale[i] = g2_ink (id_X11, cval, cval, cval);
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: phantom.cpp,v 1.6 2000/07/13 07:03:21 kevin Exp $
+** $Id: phantom.cpp,v 1.7 2000/07/15 08:36:13 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
ymax = ymin + wsize;
printf("Drawing Phantom:\n\n");
- printf(" data limits: %9.3g, %9.3g, %9.3g, %9.3g\n",
- m_xmin, m_ymin, m_xmax, m_ymax);
- printf(" window size: %9.3g, %9.3g, %9.3g, %9.3g\n",
- xmin, ymin, xmax, ymax);
+ printf(" data limits: %9.3g, %9.3g, %9.3g, %9.3g\n", m_xmin, m_ymin, m_xmax, m_ymax);
+ printf(" window size: %9.3g, %9.3g, %9.3g, %9.3g\n", xmin, ymin, xmax, ymax);
- gid = sgp2_init(0, 0, "Phantom Show");
+ gid = sgp2_init (0, 0, "Phantom Show");
sgp2_window (xmin, ymin, xmax, ymax);
draw();
- termgrf2();
+ sgp2_close (gid);
}
#endif
void
Phantom::addStdRowland (void)
{
- addPElem("ellipse", 0.0000, 0.0000, 0.6900, 0.9200, 0.0, 1.00);
- addPElem("ellipse", 0.0000, -0.0184, 0.6624, 0.8740, 0.0, -0.98);
- addPElem("ellipse", 0.2200, 0.0000, 0.1100, 0.3100, -18.0, -0.02);
- addPElem("ellipse", -0.2200, 0.0000, 0.1600, 0.4100, 18.0, -0.02);
- addPElem("ellipse", 0.0000, 0.3500, 0.2100, 0.2500, 0.0, 0.01);
- addPElem("ellipse", 0.0000, 0.1000, 0.0460, 0.0460, 0.0, 0.01);
- addPElem("ellipse", 0.0000, -0.1000, 0.0460, 0.0460, 0.0, 0.01);
- addPElem("ellipse", -0.0800, -0.6050, 0.0460, 0.0230, 0.0, 0.01);
- addPElem("ellipse", 0.0000, -0.6050, 0.0230, 0.0230, 0.0, 0.01);
- addPElem("ellipse", 0.0600, -0.6050, 0.0230, 0.0230, 0.0, 0.01);
- addPElem("ellipse", 0.5538, -0.3858, 0.0330, 0.2060, -18.0, 0.03);
+ addPElem ("ellipse", 0.0000, 0.0000, 0.6900, 0.9200, 0.0, 1.00);
+ addPElem ("ellipse", 0.0000, -0.0184, 0.6624, 0.8740, 0.0, -0.98);
+ addPElem ("ellipse", 0.2200, 0.0000, 0.1100, 0.3100, -18.0, -0.02);
+ addPElem ("ellipse", -0.2200, 0.0000, 0.1600, 0.4100, 18.0, -0.02);
+ addPElem ("ellipse", 0.0000, 0.3500, 0.2100, 0.2500, 0.0, 0.01);
+ addPElem ("ellipse", 0.0000, 0.1000, 0.0460, 0.0460, 0.0, 0.01);
+ addPElem ("ellipse", 0.0000, -0.1000, 0.0460, 0.0460, 0.0, 0.01);
+ addPElem ("ellipse", -0.0800, -0.6050, 0.0460, 0.0230, 0.0, 0.01);
+ addPElem ("ellipse", 0.0000, -0.6050, 0.0230, 0.0230, 0.0, 0.01);
+ addPElem ("ellipse", 0.0600, -0.6050, 0.0230, 0.0230, 0.0, 0.01);
+ addPElem ("ellipse", 0.5538, -0.3858, 0.0330, 0.2060, -18.0, 0.03);
}
void
void
Phantom::addStdHerman (void)
{
- addPElem("ellipse", 0.000, 1.50, 0.375, 0.3000, 90.00, -0.003);
- addPElem("ellipse", 0.675, -0.75, 0.225, 0.1500, 140.00, 0.010);
- addPElem("ellipse", 0.750, 1.50, 0.375, 0.2250, 50.00, 0.003);
- addPElem("segment", 1.375, -7.50, 1.100, 0.6250, 19.20, -0.204);
- addPElem("segment", 1.375, -7.50, 1.100, 4.3200, 19.21, 0.204);
- addPElem("segment", 0.000, -2.25, 1.125, 0.3750, 0.00, -0.003);
- addPElem("segment", 0.000, -2.25, 1.125, 3.0000, 0.00, 0.003);
- addPElem("segment", -1.000, 3.75, 1.000, 0.5000, 135.00, -0.003);
- addPElem("segment", -1.000, 3.75, 1.000, 3.0000, 135.00, 0.003);
- addPElem("segment", 1.000, 3.75, 1.000, 0.5000, 225.00, -0.003);
- addPElem("segment", 1.000, 3.75, 1.000, 3.0000, 225.00, 0.003);
- addPElem("triangle", 5.025, 3.75, 1.125, 0.5000, 110.75, 0.206);
- addPElem("triangle",-5.025, 3.75, 1.125, 0.9000,-110.75, 0.206);
- addPElem("ellipse", 0.000, 0.00, 8.625, 6.4687, 90.00, 0.416);
- addPElem("ellipse", 0.000, 0.00, 7.875, 5.7187, 90.00, -0.206);
+ addPElem ("ellipse", 0.000, 1.50, 0.375, 0.3000, 90.00, -0.003);
+ addPElem ("ellipse", 0.675, -0.75, 0.225, 0.1500, 140.00, 0.010);
+ addPElem ("ellipse", 0.750, 1.50, 0.375, 0.2250, 50.00, 0.003);
+ addPElem ("segment", 1.375, -7.50, 1.100, 0.6250, 19.20, -0.204);
+ addPElem ("segment", 1.375, -7.50, 1.100, 4.3200, 19.21, 0.204);
+ addPElem ("segment", 0.000, -2.25, 1.125, 0.3750, 0.00, -0.003);
+ addPElem ("segment", 0.000, -2.25, 1.125, 3.0000, 0.00, 0.003);
+ addPElem ("segment", -1.000, 3.75, 1.000, 0.5000, 135.00, -0.003);
+ addPElem ("segment", -1.000, 3.75, 1.000, 3.0000, 135.00, 0.003);
+ addPElem ("segment", 1.000, 3.75, 1.000, 0.5000, 225.00, -0.003);
+ addPElem ("segment", 1.000, 3.75, 1.000, 3.0000, 225.00, 0.003);
+ addPElem ("triangle", 5.025, 3.75, 1.125, 0.5000, 110.75, 0.206);
+ addPElem ("triangle",-5.025, 3.75, 1.125, 0.9000,-110.75, 0.206);
+ addPElem ("ellipse", 0.000, 0.00, 8.625, 6.4687, 90.00, 0.416);
+ addPElem ("ellipse", 0.000, 0.00, 7.875, 5.7187, 90.00, -0.206);
}
void
Phantom::addStdHermanBordered (void)
{
- addPElem("ellipse", 0., 0., 6.6, 5.9, 90., 0.);
+ addStdHerman();
+ addPElem ("ellipse", 0.000, 0.000, 8.650, 8.650, 0.00, 0.000);
}
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: projections.cpp,v 1.14 2000/07/13 07:03:21 kevin Exp $
+** $Id: projections.cpp,v 1.15 2000/07/15 08:36:13 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
*/
bool
-Projections::reconstruct (ImageFile& im, const char* const filterName, double filt_param, const char* const filterMethodName, const int zeropad, const char* const interpName, int interpFactor, const char* const backprojectName, const int trace)
+Projections::reconstruct (ImageFile& im, const char* const filterName, double filt_param, const char* const filterMethodName, const int zeropad, const char* const interpName, int interpFactor, const char* const backprojectName, const int trace) const
{
double detInc = m_detInc;
int n_filteredProj = m_nDet * interpFactor;
if (trace >= TRACE_TEXT)
printf ("Reconstructing view %d (last = %d)\n", iview, m_nView - 1);
- DetectorArray& darray = getDetectorArray (iview);
- DetectorValue* detval = darray.detValues();
+ const DetectorArray& darray = getDetectorArray (iview);
+ const DetectorValue* detval = darray.detValues();
filter.filterSignal (detval, filteredProj);
bin_PROGRAMS=ctsim
-ctsim_SOURCES=ctsim.cpp docs.cpp views.cpp
+ctsim_SOURCES=ctsim.cpp docs.cpp views.cpp ctsim.h docs.h views.h
ctsim_DEPENDENCIES=../libctgraphics/libctgraphics.a ../libctsupport/libctsupport.a ../libctsim/libctsim.a ../include/ct.h
ctsim_LDADD=-L../libctgraphics -L../libctsupport -L../libctsim @wxlibs@
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ctsim.cpp,v 1.4 2000/07/13 07:01:59 kevin Exp $
+** $Id: ctsim.cpp,v 1.5 2000/07/15 08:36:13 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
#endif
#include "wx/docview.h"
-
+#include "ct.h"
#include "ctsim.h"
#include "docs.h"
#include "views.h"
+class CTSimApp* theApp = NULL;
+
+struct option CTSimApp::ctsimOptions[] =
+{
+ {"help", 0, 0, O_HELP},
+ {0, 0, 0, 0}
+};
+
IMPLEMENT_APP(CTSimApp)
CTSimApp::CTSimApp(void)
: m_docManager(NULL), m_pFrame(NULL)
{
+ theApp = this;
}
bool
CTSimApp::OnInit(void)
{
+ // process options
+ while (1) {
+ int c = getopt_long (argc, argv, "", ctsimOptions, NULL);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case O_HELP:
+ case '?':
+ usage (argv[0]);
+ exit (0);
+ default:
+ usage (argv[0]);
+ exit (1);
+ }
+ }
+
m_docManager = new wxDocManager;
(void) new wxDocTemplate (m_docManager, "ImageFile", "*.if", "", "if", "ImageFile doc", "ImageFile View", CLASSINFO(ImageFileDocument), CLASSINFO(ImageFileView));
(void) new wxDocTemplate (m_docManager, "ProjectionFile", "*.pj", "", "pj", "ProjectionFile doc", "ProjectionFile View", CLASSINFO(ProjectionFileDocument), CLASSINFO(ProjectionFileView));
+ (void) new wxDocTemplate (m_docManager, "PhantomFile", "*.phm", "", "phm", "Phantom doc", "Phantom View", CLASSINFO(PhantomDocument), CLASSINFO(PhantomView));
+
//// Create the main frame window
m_pFrame = new MainFrame(m_docManager, (wxFrame *) NULL, -1, "CTSim", wxPoint(0, 0), wxSize(500, 400), wxDEFAULT_FRAME_STYLE);
//// Make a menubar
wxMenu *file_menu = new wxMenu;
- // file_menu->Append(wxID_NEW, "&New...");
+ file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "&Create Phantom...");
file_menu->Append(wxID_OPEN, "&Open...");
file_menu->AppendSeparator();
m_docManager->FileHistoryUseMenu(file_menu);
wxMenu *help_menu = new wxMenu;
+ help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents");
+ help_menu->AppendSeparator();
help_menu->Append(MAINMENU_HELP_ABOUT, "&About");
wxMenuBar *menu_bar = new wxMenuBar;
m_pFrame->SetMenuBar(menu_bar);
+ SetTopWindow (m_pFrame);
m_pFrame->Centre(wxBOTH);
+
m_pFrame->Show(true);
-
- SetTopWindow (m_pFrame);
+
+ for (int i = optind + 1; i <= argc; i++) {
+ wxString filename = argv [i - 1];
+ m_docManager->CreateDocument (filename, wxDOC_SILENT);
+ }
+
return true;
}
+void
+CTSimApp::usage(const char* program)
+{
+ cout << "usage: " << fileBasename(program) << " [files-to-open...] [OPTIONS]\n";
+ cout << "Computed Tomography Simulator (Graphical Shell)\n";
+ cout << "\n";
+ cout << " --help Display this help message\n";
+}
+
int
CTSimApp::OnExit(void)
{
return 0;
}
+wxString
+CTSimApp::getUntitledFilename(void)
+{
+ static int untitledNumber = 1;
+
+ wxString filename ("Untitled");
+ filename << untitledNumber++;
+
+ return (filename);
+}
+
// Top-level window for CTSim
IMPLEMENT_CLASS(MainFrame, wxDocParentFrame)
+
BEGIN_EVENT_TABLE(MainFrame, wxDocParentFrame)
- EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout)
- EVT_MENU(MAINMENU_FILE_EXIT, MainFrame::OnExit)
+ EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout)
+ EVT_MENU(MAINMENU_HELP_CONTENTS, MainFrame::OnHelpContents)
+ EVT_MENU(MAINMENU_FILE_CREATE_PHANTOM, MainFrame::OnCreatePhantom)
+ EVT_MENU(MAINMENU_FILE_EXIT, MainFrame::OnExit)
END_EVENT_TABLE()
+
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)
+ : wxDocParentFrame(manager, frame, id, title, pos, size, type), m_pLog(NULL)
{
CreateStatusBar();
+ 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));
SetStatusText ("Welcome to CTSim");
}
void
MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
{
- wxMessageBox("CTSim\nAuthor: Kevin Rosenberg <kevin@rosenberg.net>\nUsage: ctsim", "About CTSim", wxOK | wxICON_INFORMATION, this);
+ wxMessageBox("CTSim\nAuthor: Kevin Rosenberg <kevin@rosenberg.net>\nUsage: ctsim [files-to-open..] [--help]", "About CTSim", wxOK | wxICON_INFORMATION, this);
+}
+
+void
+MainFrame::OnCreatePhantom(wxCommandEvent& WXUNUSED(event))
+{
+ wxString choiceStringList [5];
+ choiceStringList[0] = Phantom::PHM_HERMAN_STR;
+ choiceStringList[1] = Phantom::PHM_BHERMAN_STR;
+ choiceStringList[2] = Phantom::PHM_ROWLAND_STR;;
+ choiceStringList[3] = Phantom::PHM_BROWLAND_STR;
+ choiceStringList[4] = Phantom::PHM_UNITPULSE_STR;
+ wxString choiceTitleList [5];
+ choiceTitleList[0] = "Herman Head";
+ choiceTitleList[1] = "Herman Head Bordered";
+ choiceTitleList[2] = "Rowland Head";
+ choiceTitleList[3] = "Rowland Head Bordered";
+ choiceTitleList[4] = "Unit Pulse";
+ wxSingleChoiceDialog dialog (this, "Select phantom", "Phantom Selection", 5, choiceTitleList, NULL, wxOK|wxCANCEL|wxCENTRE);
+
+ int dialogReturn = dialog.ShowModal();
+ if (dialogReturn == wxID_OK) {
+ int selection = dialog.GetSelection();
+ *theApp->getLog() << "Selected phantom " << selection << "\n";
+ wxString filename = choiceStringList[selection] + ".phm";
+ theApp->getDocManager()->CreateDocument(filename, wxDOC_SILENT);
+ }
+
+}
+
+void
+MainFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event) )
+{
+ wxMessageBox("No help available, refer to man pages of command-line tools");
}
void
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ctsim.h,v 1.1 2000/07/13 07:01:59 kevin Exp $
+** $Id: ctsim.h,v 1.2 2000/07/15 08:36:13 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
#include "wx/docview.h"
+// Define a new frame
+class MainFrame: public wxDocParentFrame
+{
+ DECLARE_CLASS(MainFrame)
+private:
+ wxTextCtrl* m_pLog;
+
+public:
+ MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type);
+
+ void OnAbout (wxCommandEvent& event);
+ void OnHelpContents (wxCommandEvent& event);
+ void OnCreatePhantom (wxCommandEvent& event);
+ void OnExit (wxCommandEvent& event);
+
+ wxTextCtrl* getLog()
+ { return m_pLog; }
+
+ DECLARE_EVENT_TABLE()
+};
+
class wxDocManager;
-class MainFrame;
class CTSimApp: public wxApp
{
public:
int OnExit(void);
MainFrame* getMainFrame(void) const
{ return m_pFrame; }
+ wxTextCtrl* getLog(void)
+ { return m_pFrame->getLog(); }
+ wxDocManager* getDocManager()
+ { return m_docManager; }
+
+ wxString getUntitledFilename(void);
-protected:
+private:
wxDocManager* m_docManager;
MainFrame* m_pFrame;
-};
-DECLARE_APP(CTSimApp)
+ void usage (const char* program);
-// Define a new frame
-class MainFrame: public wxDocParentFrame
-{
- DECLARE_CLASS(MainFrame)
+ static struct option ctsimOptions[];
-public:
- MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type);
-
- void OnAbout (wxCommandEvent& event);
- void OnExit (wxCommandEvent& event);
-
- DECLARE_EVENT_TABLE()
+ enum { O_HELP };
};
-extern MainFrame *GetMainFrame(void);
+DECLARE_APP(CTSimApp)
+
+extern class CTSimApp* theApp;
enum {
MAINMENU_HELP_ABOUT = 500,
+ MAINMENU_HELP_CONTENTS,
+ MAINMENU_FILE_CREATE_PHANTOM,
MAINMENU_FILE_EXIT,
IFMENU_FILE_PROPERTIES,
PJMENU_FILE_PROPERTIES,
- PJMENU_FILE_RECONSTRUCT,
+ PHMMENU_FILE_PROPERTIES,
+ PJMENU_PROCESS_RECONSTRUCT,
+ IFMENU_VIEW_WINDOW_AUTO,
+ PHMMENU_PROCESS_RASTERIZE,
+ PHMMENU_PROCESS_PROJECTIONS,
};
#endif
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: docs.cpp,v 1.1 2000/07/13 07:01:59 kevin Exp $
+** $Id: docs.cpp,v 1.2 2000/07/15 08:36:13 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
#include "wx/wx.h"
#endif
#include "wx/txtstrm.h"
+#include "wx/file.h"
#if !wxUSE_DOC_VIEW_ARCHITECTURE
#error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
#endif
+#include "ct.h"
+#include "ctsim.h"
#include "docs.h"
#include "views.h"
-
// ImageFileDocument
IMPLEMENT_DYNAMIC_CLASS(ImageFileDocument, wxDocument)
bool ImageFileDocument::OnSaveDocument(const wxString& filename)
{
- if (!m_imageFile.fileWrite (filename))
- return false;
- Modify(false);
- return true;
+ if (! m_imageFile.fileWrite (filename)) {
+ *theApp->getLog() << "Unable to write image file " << filename << "\n";
+ return false;
+ }
+ *theApp->getLog() << "Wrote image file " << filename << "\n";
+ Modify(false);
+ return true;
}
bool ImageFileDocument::OnOpenDocument(const wxString& filename)
{
- if (! m_imageFile.fileRead (filename))
- return false;
-
+ if (filename == "untitled.if") {
+ wxString untitledFilename = theApp->getUntitledFilename();
+ SetFilename (untitledFilename, true);
+ } else {
+ if (! m_imageFile.fileRead (filename)) {
+ *theApp->getLog() << "Unable to read image file " << filename << "\n";
+ return false;
+ }
+ *theApp->getLog() << "Read image file " << filename << "\n";
SetFilename(filename, true);
- Modify(false);
- UpdateAllViews();
- return true;
+ }
+ Modify(false);
+ UpdateAllViews();
+ return true;
}
bool ImageFileDocument::IsModified(void) const
bool ProjectionFileDocument::OnSaveDocument(const wxString& filename)
{
- if (!m_projectionFile.write (filename))
- return false;
- Modify(false);
- return true;
+ if (! m_projectionFile.write (filename)) {
+ *theApp->getLog() << "Unable to write projection file " << filename << "\n";
+ return false;
+ }
+ *theApp->getLog() << "Wrote projection file " << filename << "\n";
+ Modify(false);
+ return true;
}
bool ProjectionFileDocument::OnOpenDocument(const wxString& filename)
{
- if (! m_projectionFile.read (filename))
- return false;
-
+ if (filename == "untitled.pj") {
+ wxString untitledFilename = theApp->getUntitledFilename();
+ SetFilename (untitledFilename, true);
+ } else {
+ if (! m_projectionFile.read (filename)) {
+ *theApp->getLog() << "Unable to read projection file " << filename << "\n";
+ return false;
+ }
+ *theApp->getLog() << "Read projection file " << filename << "\n";
SetFilename(filename, true);
- Modify(false);
- UpdateAllViews();
- return true;
+ }
+ Modify(false);
+ UpdateAllViews();
+ return true;
}
bool ProjectionFileDocument::IsModified(void) const
{
wxDocument::Modify(mod);
}
+
+
+// PhantomDocument
+
+IMPLEMENT_DYNAMIC_CLASS(PhantomDocument, wxDocument)
+
+bool PhantomDocument::OnOpenDocument(const wxString& filename)
+{
+ wxString myFilename = filename;
+ if (wxFile::Exists (myFilename)) {
+ m_phantom.createFromFile (myFilename);
+ } else {
+ myFilename.Replace (".phm", "");
+ m_phantom.createFromPhantom (myFilename);
+ }
+ m_namePhantom = myFilename;
+ SetFilename (myFilename, true);
+ if (m_phantom.fail()) {
+ *theApp->getLog() << "Failure creating phantom " << myFilename << "\n";
+ return false;
+ }
+ m_idPhantom = m_phantom.id();
+ Modify(false);
+ UpdateAllViews();
+ return true;
+}
+
+bool PhantomDocument::IsModified(void) const
+{
+ return wxDocument::IsModified();
+}
+
+void PhantomDocument::Modify(bool mod)
+{
+ wxDocument::Modify(mod);
+}
+
/*****************************************************************************
** FILE IDENTIFICATION
**
-** Name: doc.h
+** Name: docs.h
** Purpose: Header file for Document routines of CTSim program
** Programmer: Kevin Rosenberg
** Date Started: July 2000
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: docs.h,v 1.1 2000/07/13 07:01:59 kevin Exp $
+** $Id: docs.h,v 1.2 2000/07/15 08:36:13 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
ImageFile m_imageFile;
public:
- virtual bool OnSaveDocument(const wxString& filename);
- virtual bool OnOpenDocument(const wxString& filename);
- virtual bool IsModified(void) const;
- virtual void Modify(bool mod);
+ virtual bool OnSaveDocument (const wxString& filename);
+ virtual bool OnOpenDocument (const wxString& filename);
+ virtual bool IsModified (void) const;
+ virtual void Modify (bool mod);
- ImageFileDocument(void) {}
- ~ImageFileDocument(void) {}
+ ImageFileDocument (void) {}
+ ~ImageFileDocument (void) {}
const ImageFile& getImageFile(void) const
{ return m_imageFile; }
Projections m_projectionFile;
public:
- virtual bool OnSaveDocument(const wxString& filename);
- virtual bool OnOpenDocument(const wxString& filename);
- virtual bool IsModified(void) const;
- virtual void Modify(bool mod);
+ virtual bool OnSaveDocument (const wxString& filename);
+ virtual bool OnOpenDocument (const wxString& filename);
+ virtual bool IsModified (void) const;
+ virtual void Modify (bool mod);
- ProjectionFileDocument(void) {}
- ~ProjectionFileDocument(void) {}
+ ProjectionFileDocument (void) {}
+ ~ProjectionFileDocument (void) {}
- const Projections& getProjections(void) const
+ const Projections& getProjections (void) const
{ return m_projectionFile; }
- Projections& getProjections(void)
+ Projections& getProjections (void)
{ return m_projectionFile; }
};
-class TextEditDocument: public wxDocument
+
+class PhantomDocument: public wxDocument
{
- DECLARE_DYNAMIC_CLASS(TextEditDocument)
+ DECLARE_DYNAMIC_CLASS(PhantomDocument)
+
private:
+ Phantom m_phantom;
+ Phantom::PhantomID m_idPhantom;
+ wxString m_namePhantom;
+
public:
- virtual bool OnSaveDocument(const wxString& filename);
- virtual bool OnOpenDocument(const wxString& filename);
- virtual bool IsModified(void) const;
- virtual void Modify(bool mod);
-
- TextEditDocument(void) {}
- ~TextEditDocument(void) {}
+ PhantomDocument (void)
+ : m_idPhantom(Phantom::PHM_INVALID)
+ {}
+
+ ~PhantomDocument (void)
+ {}
+
+ const Phantom::PhantomID getPhantomID (void) const
+ { return m_idPhantom; }
+
+ const wxString& getPhantomName (void) const
+ { return m_namePhantom; }
+
+ const Phantom& getPhantom (void) const
+ { return m_phantom; }
+
+ Phantom& getPhantom (void)
+ { return m_phantom; }
+
+ virtual bool OnOpenDocument (const wxString& filename);
+ virtual bool IsModified (void) const;
+ virtual void Modify (bool mod);
};
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: views.cpp,v 1.1 2000/07/13 07:01:59 kevin Exp $
+** $Id: views.cpp,v 1.2 2000/07/15 08:36:13 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
#error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
#endif
+#include "wx/image.h"
+
+#include "ct.h"
#include "ctsim.h"
#include "docs.h"
#include "views.h"
#include <sstream>
#include "ct.h"
-//#include "imagefile.h"
-//#include "phantom.h"
-//#include "scanner.h"
-//#include "projections.h"
// ImageFileCanvas
wxClientDC dc(this);
PrepareDC(dc);
- dc.SetPen(*wxBLACK_PEN);
-
wxPoint pt(event.GetLogicalPosition(dc));
- if (event.LeftUp())
- cout << pt.x << "x" << pt.y << endl;
+ if (event.LeftUp()) {
+ const ImageFile& rIF = m_pView->GetDocument()->getImageFile();
+ ImageFileArrayConst v = rIF.getArray();
+ int nx = rIF.nx();
+ int ny = rIF.ny();
+
+ if (pt.x >= 0 && pt.x < nx && pt.y >= 0 & pt.y < ny) {
+ ostringstream os;
+ os << "Image value (" << pt.x << "," << pt.y << ") = " << v[pt.x][pt.y] << "\n";
+ *theApp->getLog() << os.str().c_str();
+ } else
+ *theApp->getLog() << "Mouse out of image range (" << pt.x << "," << pt.y << ")\n";
+
+ }
}
BEGIN_EVENT_TABLE(ImageFileView, wxView)
EVT_MENU(IFMENU_FILE_PROPERTIES, ImageFileView::OnProperties)
+ EVT_MENU(IFMENU_VIEW_WINDOW_AUTO, ImageFileView::OnWindowAuto)
END_EVENT_TABLE()
-bool ImageFileView::m_bPColoursInitialized = false;
-wxColour* ImageFileView::m_pColours[256];
-
ImageFileView::ImageFileView(void)
: wxView(), m_canvas(NULL), m_frame(NULL), m_bMinSpecified(false), m_bMaxSpecified(false)
{
- if (! m_bPColoursInitialized) {
- for (int i = 0; i < 256; i++)
- m_pColours[i] = new wxColour (i, i, i);
-
- m_bPColoursInitialized = true;
- }
}
ImageFileView::~ImageFileView(void)
ImageFileView::OnProperties (wxCommandEvent& event)
{
double min, max, mean, mode, median, stddev;
- const ImageFile& rIF = dynamic_cast<ImageFileDocument*>(GetDocument())->getImageFile();
- const string& rFilename = rIF.getFilename();
- rIF.statistics (min, max, mean, mode, median, stddev);
- ostringstream os;
- os << "file: " << rFilename << "\nmin: "<<min<<"\nmax: "<<max<<"\nmean: "<<mean<<"\nmode: "<<mode<<"\nstddev: "<<stddev;
- wxMessageBox(os.str().c_str(), "Image Properties", wxOK | wxICON_INFORMATION, m_frame);
+ const ImageFile& rIF = GetDocument()->getImageFile();
+ if (rIF.nx() == 0 || rIF.ny() == 0)
+ *theApp->getLog() << "Properties: empty imagefile\n";
+ else {
+ const string& rFilename = rIF.getFilename();
+ rIF.statistics (min, max, mean, mode, median, stddev);
+ ostringstream os;
+ os << "file: " << rFilename << "\nmin: "<<min<<"\nmax: "<<max<<"\nmean: "<<mean<<"\nmode: "<<mode<<"\nstddev: "<<stddev;
+ *theApp->getLog() << os.str().c_str();
+ }
+}
+
+void
+ImageFileView::OnWindowAuto (wxCommandEvent& event)
+{
+ *theApp->getLog() << "ImageFile: Window Auto\n";
+ m_minPixel = .2;
+ m_maxPixel = .22;
+ m_bMinSpecified = true;
+ m_bMaxSpecified = true;
+ OnUpdate(this, NULL);
}
wxFrame*
ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
{
- wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, dynamic_cast<CTSimApp*>(wxTheApp)->getMainFrame(), -1, "ImageFile Frame", wxPoint(10, 10), wxSize(300, 300), wxDEFAULT_FRAME_STYLE);
+ wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "ImageFile Frame", wxPoint(10, 10), wxSize(300, 300), wxDEFAULT_FRAME_STYLE);
wxMenu *file_menu = new wxMenu;
- file_menu->Append(wxID_NEW, "&New...");
file_menu->Append(wxID_OPEN, "&Open...");
file_menu->Append(wxID_CLOSE, "&Close");
file_menu->Append(wxID_SAVE, "&Save");
file_menu->Append(wxID_PRINT_SETUP, "Print &Setup...");
file_menu->Append(wxID_PREVIEW, "Print Pre&view");
+ wxMenu *view_menu = new wxMenu;
+ view_menu->Append(IFMENU_VIEW_WINDOW_AUTO, "&Window auto");
+
wxMenu *help_menu = new wxMenu;
help_menu->Append(MAINMENU_HELP_ABOUT, "&About");
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
+ menu_bar->Append(view_menu, "&View");
menu_bar->Append(help_menu, "&Help");
subframe->SetMenuBar(menu_bar);
void
ImageFileView::OnDraw (wxDC* dc)
{
- const ImageFile& rIF = dynamic_cast<ImageFileDocument*>(GetDocument())->getImageFile();
- dc->Blit(static_cast<wxCoord>(0), static_cast<wxCoord>(0), static_cast<wxCoord>(rIF.nx()), static_cast<wxCoord>(rIF.ny()), &m_memoryDC, static_cast<wxCoord>(0), static_cast<wxCoord>(0));
+ if (m_bitmap.Ok())
+ dc->DrawBitmap(m_bitmap, 0, 0, false);
}
}
double scaleWidth = m_maxPixel - m_minPixel;
- m_pBitmap = new wxBitmap (rIF.nx(), rIF.ny());
- m_memoryDC.SelectObject (*m_pBitmap);
- m_memoryDC.BeginDrawing();
-
- wxPen pen (*m_pColours[128], 1, wxDOT);
- m_memoryDC.SetPen (pen);
+ unsigned char imageData [nx * ny * 3];
for (int ix = 0; ix < nx; ix++) {
for (int iy = 0; iy < ny; iy++) {
double scaleValue = ((v[ix][iy] - m_minPixel) / scaleWidth) * 255;
int intensity = static_cast<int>(scaleValue + 0.5);
intensity = clamp (intensity, 0, 255);
- pen.SetColour (*m_pColours[intensity]);
- m_memoryDC.SetPen(pen);
- m_memoryDC.DrawPoint(ix, ny - iy);
+ int baseAddr = ((ny - 1 - iy) * nx + ix) * 3;
+ imageData[baseAddr] = imageData[baseAddr+1] = imageData[baseAddr+2] = intensity;
}
}
+ wxImage image (ny, nx, imageData, true);
+ m_bitmap = image.ConvertToBitmap();
}
- m_memoryDC.EndDrawing();
if (m_canvas) {
- // m_canvas->SetScrollbars (50, 50, nx / 50, ny / 50, 0, 0, false);
m_canvas->Refresh();
}
m_canvas->Clear();
m_canvas->m_pView = NULL;
m_canvas = NULL;
- wxString s(wxTheApp->GetAppName());
+ wxString s(theApp->GetAppName());
if (m_frame)
m_frame->SetTitle(s);
SetFrame(NULL);
-// ProjectionFileCanvas
+// PhantomCanvas
+
+PhantomCanvas::PhantomCanvas (PhantomView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style)
+ : wxScrolledWindow(frame, -1, pos, size, style)
+{
+ m_pView = v;
+}
+
+void
+PhantomCanvas::OnDraw(wxDC& dc)
+{
+ if (m_pView)
+ m_pView->OnDraw(& dc);
+}
+
+// PhantomView
+
+IMPLEMENT_DYNAMIC_CLASS(PhantomView, wxView)
+
+BEGIN_EVENT_TABLE(PhantomView, wxView)
+ EVT_MENU(PHMMENU_FILE_PROPERTIES, PhantomView::OnProperties)
+ EVT_MENU(PHMMENU_PROCESS_RASTERIZE, PhantomView::OnRasterize)
+ EVT_MENU(PHMMENU_PROCESS_PROJECTIONS, PhantomView::OnProjections)
+END_EVENT_TABLE()
+
+PhantomView::PhantomView(void)
+ : wxView(), m_canvas(NULL), m_frame(NULL)
+{
+}
+
+PhantomView::~PhantomView(void)
+{
+}
+
+void
+PhantomView::OnProperties (wxCommandEvent& event)
+{
+ const Phantom::PhantomID idPhantom = GetDocument()->getPhantomID();
+ const string& namePhantom = GetDocument()->getPhantomName();
+ ostringstream os;
+ os << "Phantom " << namePhantom << " (" << static_cast<int>(idPhantom) << ")\n";
+ *theApp->getLog() << os.str().c_str();
+ const Phantom& rPhantom = GetDocument()->getPhantom();
+#if DEBUG
+ rPhantom.print();
+#endif
+}
+
+
+void
+PhantomView::OnProjections (wxCommandEvent& event)
+{
+}
+
+
+void
+PhantomView::OnRasterize (wxCommandEvent& event)
+{
+ const Phantom& rPhantom = GetDocument()->getPhantom();
+ ImageFileDocument* pRasterDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));
+ ImageFile& imageFile = pRasterDoc->getImageFile();
+ imageFile.setArraySize (256, 256);
+ imageFile.arrayDataClear();
+ rPhantom.convertToImagefile (imageFile, 1, TRACE_NONE);
+ pRasterDoc->Modify(true);
+ pRasterDoc->UpdateAllViews(this);
+}
+
+
+PhantomCanvas*
+PhantomView::CreateCanvas (wxView *view, wxFrame *parent)
+{
+ PhantomCanvas* pCanvas;
+ int width, height;
+ parent->GetClientSize(&width, &height);
+
+ pCanvas = new PhantomCanvas (dynamic_cast<PhantomView*>(view), parent, wxPoint(0, 0), wxSize(width, height), 0);
+
+ pCanvas->SetScrollbars(20, 20, 50, 50);
+ pCanvas->SetBackgroundColour(*wxWHITE);
+ pCanvas->Clear();
+
+ return pCanvas;
+}
+
+wxFrame*
+PhantomView::CreateChildFrame(wxDocument *doc, wxView *view)
+{
+ wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(300, 300), wxDEFAULT_FRAME_STYLE);
+
+ wxMenu *file_menu = new wxMenu;
+
+ file_menu->Append(wxID_OPEN, "&Open...");
+ file_menu->Append(wxID_CLOSE, "&Close");
+
+ file_menu->AppendSeparator();
+ file_menu->Append(PHMMENU_FILE_PROPERTIES, "P&roperties");
+
+ file_menu->AppendSeparator();
+ file_menu->Append(wxID_PRINT, "&Print...");
+ file_menu->Append(wxID_PRINT_SETUP, "Print &Setup...");
+ file_menu->Append(wxID_PREVIEW, "Print Pre&view");
+
+ wxMenu *process_menu = new wxMenu;
+ process_menu->Append(PHMMENU_PROCESS_RASTERIZE, "&Rasterize...");
+ process_menu->Append(PHMMENU_PROCESS_PROJECTIONS, "&Projections...");
+
+ wxMenu *help_menu = new wxMenu;
+ help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents");
+ help_menu->Append(MAINMENU_HELP_ABOUT, "&About");
+
+ wxMenuBar *menu_bar = new wxMenuBar;
+
+ menu_bar->Append(file_menu, "&File");
+ menu_bar->Append(process_menu, "&Process");
+ menu_bar->Append(help_menu, "&Help");
+
+ subframe->SetMenuBar(menu_bar);
+
+ subframe->Centre(wxBOTH);
+
+ return subframe;
+}
+
+
+bool
+PhantomView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
+{
+ m_frame = CreateChildFrame(doc, this);
+
+ int width, height;
+ m_frame->GetClientSize(&width, &height);
+ m_frame->SetTitle("PhantomView");
+ m_canvas = CreateCanvas(this, m_frame);
+
+#ifdef __X__
+ int x, y; // X requires a forced resize
+ m_frame->GetSize(&x, &y);
+ m_frame->SetSize(-1, -1, x, y);
+#endif
+
+ m_frame->Show(true);
+ Activate(true);
+
+ return true;
+}
+
+void
+PhantomView::OnDraw (wxDC* dc)
+{
+ // if (m_bitmap.Ok())
+ // dc->DrawBitmap (m_bitmap, 0, 0, false);
+}
+
+
+void
+PhantomView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
+{
+ if (m_canvas) {
+ m_canvas->Refresh();
+ }
+
+#ifdef __WXMSW__
+ if (m_canvas)
+ m_canvas->Refresh();
+#else
+ if (m_canvas) {
+ wxClientDC dc(m_canvas);
+ dc.Clear();
+ OnDraw (&dc);
+ }
+#endif
+}
+
+bool
+PhantomView::OnClose (bool deleteWindow)
+{
+ if (!GetDocument()->Close())
+ return false;
+
+ m_canvas->Clear();
+ m_canvas->m_pView = NULL;
+ m_canvas = NULL;
+ wxString s(wxTheApp->GetAppName());
+ if (m_frame)
+ m_frame->SetTitle(s);
+ SetFrame(NULL);
+
+ Activate(false);
+
+ if (deleteWindow) {
+ delete m_frame;
+ return true;
+ }
+ return true;
+}
+
+
+// ProjectionCanvas
ProjectionFileCanvas::ProjectionFileCanvas (ProjectionFileView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style)
: wxScrolledWindow(frame, -1, pos, size, style)
BEGIN_EVENT_TABLE(ProjectionFileView, wxView)
EVT_MENU(PJMENU_FILE_PROPERTIES, ProjectionFileView::OnProperties)
- EVT_MENU(PJMENU_FILE_RECONSTRUCT, ProjectionFileView::OnReconstruct)
+ EVT_MENU(PJMENU_PROCESS_RECONSTRUCT, ProjectionFileView::OnReconstruct)
END_EVENT_TABLE()
-bool ProjectionFileView::m_bPColoursInitialized = false;
-wxColour* ProjectionFileView::m_pColours[256];
-
ProjectionFileView::ProjectionFileView(void)
: wxView(), m_canvas(NULL), m_frame(NULL)
{
- if (! m_bPColoursInitialized) {
- for (int i = 0; i < 256; i++)
- m_pColours[i] = new wxColour (i, i, i);
-
- m_bPColoursInitialized = true;
- }
}
ProjectionFileView::~ProjectionFileView(void)
void
ProjectionFileView::OnProperties (wxCommandEvent& event)
{
- const Projections& rProj = dynamic_cast<ProjectionFileDocument*>(GetDocument())->getProjections();
- const string& rFilename = rProj.getFilename();
+ const Projections& rProj = GetDocument()->getProjections();
ostringstream os;
- os << "file: " << rFilename << "\nDetectors: " << rProj.nDet() << "\nViews: " << rProj.nView();
- wxMessageBox(os.str().c_str(), "Projection Properties", wxOK | wxICON_INFORMATION, m_frame);
+ os << "ProjectionFile " << rProj.getFilename() << ": Number of Detectors = " << rProj.nDet() << ", Number of Views = " << rProj.nView() << "\n";
+ *theApp->getLog() << os.str().c_str();
}
void
ProjectionFileView::OnReconstruct (wxCommandEvent& event)
{
- const Projections& rProj = dynamic_cast<ProjectionFileDocument*>(GetDocument())->getProjections();
- const string& rFilename = rProj.getFilename();
- ostringstream os;
- os << "Reconstruct file " << rFilename;
- wxMessageBox(os.str().c_str(), "Reconstruction Dialog", wxOK | wxICON_INFORMATION, m_frame);
+ ImageFileDocument* pReconDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));
+ ImageFile& imageFile = pReconDoc->getImageFile();
+ const Projections& rProj = GetDocument()->getProjections();
+ string optFilterName = "abs_bandlimit";
+ double optFilterParam = 1.;
+ string optFilterMethodName = "convolution";
+ int optZeropad = 3;
+ string optInterpName = "linear";
+ int optInterpParam = 1;
+ string optBackprojectName = "idiff3";
+ imageFile.setArraySize (256, 256);
+ rProj.reconstruct (imageFile, optFilterName.c_str(), optFilterParam, optFilterMethodName.c_str(), optZeropad, optInterpName.c_str(), optInterpParam, optBackprojectName.c_str(), TRACE_NONE);
+ pReconDoc->Modify(true);
+ pReconDoc->UpdateAllViews(this);
}
wxFrame*
ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
{
- wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, dynamic_cast<CTSimApp*>(wxTheApp)->getMainFrame(), -1, "ProjectionFile Frame", wxPoint(10, 10), wxSize(300, 300), wxDEFAULT_FRAME_STYLE);
+ wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Projection Frame", wxPoint(10, 10), wxSize(300, 300), wxDEFAULT_FRAME_STYLE);
wxMenu *file_menu = new wxMenu;
- file_menu->Append(wxID_NEW, "&New...");
file_menu->Append(wxID_OPEN, "&Open...");
file_menu->Append(wxID_CLOSE, "&Close");
- file_menu->Append(wxID_SAVE, "&Save");
- file_menu->Append(wxID_SAVEAS, "Save &As...");
file_menu->AppendSeparator();
- file_menu->Append(PJMENU_FILE_RECONSTRUCT, "R&econstuct");
file_menu->Append(PJMENU_FILE_PROPERTIES, "P&roperties");
file_menu->AppendSeparator();
file_menu->Append(wxID_PRINT_SETUP, "Print &Setup...");
file_menu->Append(wxID_PREVIEW, "Print Pre&view");
+ wxMenu *process_menu = new wxMenu;
+ process_menu->Append(PJMENU_PROCESS_RECONSTRUCT, "R&econstruct...");
+
wxMenu *help_menu = new wxMenu;
+ help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents");
+ help_menu->AppendSeparator();
help_menu->Append(MAINMENU_HELP_ABOUT, "&About");
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
+ menu_bar->Append(process_menu, "&Process");
menu_bar->Append(help_menu, "&Help");
subframe->SetMenuBar(menu_bar);
void
ProjectionFileView::OnDraw (wxDC* dc)
{
- const Projections& rProj = dynamic_cast<ProjectionFileDocument*>(GetDocument())->getProjections();
- dc->Blit(static_cast<wxCoord>(0), static_cast<wxCoord>(0), static_cast<wxCoord>(rProj.nDet()), static_cast<wxCoord>(rProj.nView()), &m_memoryDC, static_cast<wxCoord>(0), static_cast<wxCoord>(0));
+ if (m_bitmap.Ok())
+ dc->DrawBitmap (m_bitmap, 0, 0, false);
}
void
ProjectionFileView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
{
- const Projections& rProj = dynamic_cast<ProjectionFileDocument*>(GetDocument())->getProjections();
- const DetectorArray& detarray = rProj.getDetectorArray (0);
+ const Projections& rProj = GetDocument()->getProjections();
+ const int nDet = rProj.nDet();
+ const int nView = rProj.nView();
+ const DetectorArray& detarray = rProj.getDetectorArray(0);
const DetectorValue* detval = detarray.detValues();
double min = detval[0];
double max = detval[0];
- for (int iy = 0; iy < rProj.nView(); iy++) {
- const DetectorArray& detarray = rProj.getDetectorArray (iy);
- detval = detarray.detValues();
- for (int ix = 0; ix < rProj.nDet(); ix++) {
+ for (int iy = 0; iy < nView; iy++) {
+ const DetectorArray& detarray = rProj.getDetectorArray(iy);
+ const DetectorValue* detval = detarray.detValues();
+ for (int ix = 0; ix < nDet; ix++) {
if (min > detval[ix])
min = detval[ix];
else if (max < detval[ix])
}
}
- double scaleWidth = max - min;
-
- m_pBitmap = new wxBitmap (rProj.nDet(), rProj.nView());
- m_memoryDC.SelectObject (*m_pBitmap);
- m_memoryDC.BeginDrawing();
-
- wxPen pen (*m_pColours[128], 1, wxDOT);
- m_memoryDC.SetPen (pen);
- for (int iy = 0; iy < rProj.nView(); iy++) {
- const DetectorArray& detarray = rProj.getDetectorArray (iy);
- detval = detarray.detValues();
- for (int ix = 0; ix < rProj.nDet(); ix++) {
- double scaleValue = ((detval[ix] - min) / scaleWidth) * 255;
- int intensity = static_cast<int>(scaleValue + 0.5);
- intensity = clamp (intensity, 0, 255);
- pen.SetColour (*m_pColours[intensity]);
- m_memoryDC.SetPen(pen);
- m_memoryDC.DrawPoint(ix, iy);
+ unsigned char imageData [nDet * nView * 3];
+ double scale = (max - min) / 255;
+ for (int iy = 0; iy < nView; iy++) {
+ const DetectorArray& detarray = rProj.getDetectorArray(iy);
+ const DetectorValue* detval = detarray.detValues();
+ for (int ix = 0; ix < nDet; ix++) {
+ int intensity = static_cast<int>(((detval[ix] - min) / scale) + 0.5);
+ intensity = clamp(intensity, 0, 255);
+ int baseAddr = (iy * nDet + ix) * 3;
+ imageData[baseAddr] = imageData[baseAddr+1] = imageData[baseAddr+2] = intensity;
}
}
- m_memoryDC.EndDrawing();
-
+ wxImage image (nDet, nView, imageData, true);
+ m_bitmap = image.ConvertToBitmap();
+
if (m_canvas) {
- // m_canvas->SetScrollbars (50, 50, nx / 50, ny / 50, 0, 0, false);
m_canvas->Refresh();
}
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: views.h,v 1.1 2000/07/13 07:01:59 kevin Exp $
+** $Id: views.h,v 1.2 2000/07/15 08:36:13 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
#define __VIEWSH__
#include "wx/wx.h"
+#include "docs.h"
#include "imagefile.h"
class ImageFileCanvas;
DECLARE_DYNAMIC_CLASS(ImageFileView)
wxMemoryDC m_memoryDC;
- wxBitmap* m_pBitmap;
+ wxBitmap m_bitmap;
private:
ImageFileCanvas *CreateCanvas(wxView *view, wxFrame *parent);
double m_minPixel;
double m_maxPixel;
- static bool m_bPColoursInitialized;
- static wxColour* m_pColours[256];
-
public:
ImageFileView(void);
~ImageFileView(void);
void OnUpdate(wxView *sender, wxObject *hint = NULL);
bool OnClose (bool deleteWindow = true);
void OnProperties (wxCommandEvent& event);
+ void OnWindowAuto (wxCommandEvent& event);
+
+ ImageFileDocument* GetDocument(void)
+ { return dynamic_cast<ImageFileDocument*>(wxView::GetDocument()); }
DECLARE_EVENT_TABLE()
};
};
-class MyTextWindow: public wxTextCtrl
-{
-public:
- wxView *m_pView;
-
- MyTextWindow(wxView *v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style);
-};
-
-
-class TextEditView: public wxView
-{
- DECLARE_DYNAMIC_CLASS(TextEditView)
-private:
- wxFrame *CreateChildFrame(wxDocument *doc, wxView *view);
-
-public:
- wxFrame *frame;
- MyTextWindow *textsw;
-
- TextEditView(): wxView() { frame = (wxFrame *) NULL; textsw = (MyTextWindow *) NULL; }
- ~TextEditView(void) {}
-
- bool OnCreate(wxDocument *doc, long flags);
- void OnDraw(wxDC* dc);
- void OnUpdate(wxView *sender, wxObject *hint = (wxObject *) NULL);
- bool OnClose(bool deleteWindow = TRUE);
-};
-
class ProjectionFileCanvas;
class ProjectionFileView : public wxView
{
DECLARE_DYNAMIC_CLASS(ProjectionFileView)
wxMemoryDC m_memoryDC;
- wxBitmap* m_pBitmap;
+ wxBitmap m_bitmap;
private:
ProjectionFileCanvas *CreateCanvas(wxView *view, wxFrame *parent);
ProjectionFileCanvas *m_canvas;
wxFrame *m_frame;
- static bool m_bPColoursInitialized;
- static wxColour* m_pColours[256];
-
public:
ProjectionFileView(void);
~ProjectionFileView(void);
void OnProperties (wxCommandEvent& event);
void OnReconstruct (wxCommandEvent& event);
+ ProjectionFileDocument* GetDocument(void)
+ { return dynamic_cast<ProjectionFileDocument*>(wxView::GetDocument()); }
DECLARE_EVENT_TABLE()
};
};
+class PhantomCanvas;
+class PhantomView : public wxView
+{
+ DECLARE_DYNAMIC_CLASS(PhantomView)
+
+private:
+ PhantomCanvas *CreateCanvas(wxView *view, wxFrame *parent);
+ wxFrame *CreateChildFrame(wxDocument *doc, wxView *view);
+
+ PhantomCanvas *m_canvas;
+ wxFrame *m_frame;
+
+public:
+ PhantomView(void);
+ ~PhantomView(void);
+
+ bool OnCreate(wxDocument *doc, long flags);
+ void OnDraw(wxDC* dc);
+ void OnUpdate(wxView *sender, wxObject *hint = NULL);
+ bool OnClose (bool deleteWindow = true);
+ void OnProperties (wxCommandEvent& event);
+ void OnRasterize (wxCommandEvent& event);
+ void OnProjections (wxCommandEvent& event);
+
+ PhantomDocument* GetDocument(void)
+ { return dynamic_cast<PhantomDocument*>(wxView::GetDocument()); }
+
+ DECLARE_EVENT_TABLE()
+};
+
+class PhantomCanvas: public wxScrolledWindow
+{
+public:
+ PhantomView* m_pView;
+
+ PhantomCanvas (PhantomView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style);
+ virtual void OnDraw(wxDC& dc);
+
+};
+
+
#endif
+
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: pjrec.cpp,v 1.1 2000/07/13 07:01:35 kevin Exp $
+** $Id: pjrec.cpp,v 1.2 2000/07/15 08:36:13 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
string optFilterMethodName = SignalFilter::FILTER_METHOD_CONVOLUTION_STR;
string optInterpName = Backprojector::INTERP_LINEAR_STR;
string optBackprojName = Backprojector::BPROJ_IDIFF2_STR;
- // string optFilterMethodName = SignalFilter::FILTER_METHOD_CONVOLUTION_STR;
int optPreinterpolationFactor = 1;
int nx, ny;
#ifdef HAVE_MPI