X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=src%2Fviews.cpp;h=21fc80a15b5a19370761d784b3c63313d7fcad93;hp=8a555ce2cc4e705ebb9708a8c63a8418edc8cca4;hb=e4c1f7f8eb87558c3abf3bf1d20732361f425351;hpb=ebe18bbc459204f8bf89880459804cc643a32f24 diff --git a/src/views.cpp b/src/views.cpp index 8a555ce..21fc80a 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.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 @@ -44,15 +44,14 @@ #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 #include "ct.h" -//#include "imagefile.h" -//#include "phantom.h" -//#include "scanner.h" -//#include "projections.h" // ImageFileCanvas @@ -83,12 +82,22 @@ ImageFileCanvas::OnMouseEvent(wxMouseEvent& event) 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"; + + } } @@ -98,20 +107,12 @@ IMPLEMENT_DYNAMIC_CLASS(ImageFileView, wxView) 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) @@ -122,12 +123,27 @@ void ImageFileView::OnProperties (wxCommandEvent& event) { double min, max, mean, mode, median, stddev; - const ImageFile& rIF = dynamic_cast(GetDocument())->getImageFile(); - const string& rFilename = rIF.getFilename(); - rIF.statistics (min, max, mean, mode, median, stddev); - ostringstream os; - os << "file: " << rFilename << "\nmin: "<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: "<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); } @@ -150,11 +166,10 @@ ImageFileView::CreateCanvas (wxView *view, wxFrame *parent) wxFrame* ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view) { - wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, dynamic_cast(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"); @@ -168,12 +183,16 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view) 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); @@ -212,8 +231,8 @@ ImageFileView::OnCreate(wxDocument *doc, long WXUNUSED(flags) ) void ImageFileView::OnDraw (wxDC* dc) { - const ImageFile& rIF = dynamic_cast(GetDocument())->getImageFile(); - dc->Blit(static_cast(0), static_cast(0), static_cast(rIF.nx()), static_cast(rIF.ny()), &m_memoryDC, static_cast(0), static_cast(0)); + if (m_bitmap.Ok()) + dc->DrawBitmap(m_bitmap, 0, 0, false); } @@ -235,27 +254,21 @@ ImageFileView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) ) } 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(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(); } @@ -280,7 +293,7 @@ ImageFileView::OnClose (bool deleteWindow) 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); @@ -296,7 +309,205 @@ ImageFileView::OnClose (bool deleteWindow) -// 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(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(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(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) @@ -317,21 +528,12 @@ IMPLEMENT_DYNAMIC_CLASS(ProjectionFileView, wxView) 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) @@ -341,22 +543,30 @@ ProjectionFileView::~ProjectionFileView(void) void ProjectionFileView::OnProperties (wxCommandEvent& event) { - const Projections& rProj = dynamic_cast(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(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(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); } @@ -379,18 +589,14 @@ ProjectionFileView::CreateCanvas (wxView *view, wxFrame *parent) wxFrame* ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view) { - wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, dynamic_cast(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(); @@ -398,12 +604,18 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view) 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); @@ -439,23 +651,25 @@ ProjectionFileView::OnCreate(wxDocument *doc, long WXUNUSED(flags) ) void ProjectionFileView::OnDraw (wxDC* dc) { - const Projections& rProj = dynamic_cast(GetDocument())->getProjections(); - dc->Blit(static_cast(0), static_cast(0), static_cast(rProj.nDet()), static_cast(rProj.nView()), &m_memoryDC, static_cast(0), static_cast(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(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]) @@ -463,30 +677,22 @@ ProjectionFileView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) } } - 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(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(((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(); }