00001 #include "vislu_frame.h"
00002 #include <wx/filedlg.h>
00003 #include <wx/msgdlg.h>
00004 #include <wx/valgen.h>
00005 #include <wx/valtext.h>
00006 #include <wx/aboutdlg.h>
00007
00008 namespace
00009 {
00010
00011 static struct { int value; Viewmode mode; } viewmodemap[] = {
00012 {0, VM_3D},
00013 {1, VM_SLICE_X},
00014 {2, VM_SLICE_Y},
00015 {3, VM_SLICE_Z}
00016 };
00017
00018 int ViewmodeFromVolumeCanvas(Viewmode vm)
00019 {
00020 for (int i = 0; i < 4; ++i)
00021 if (viewmodemap[i].mode == vm) return viewmodemap[i].value;
00022 return 0;
00023 }
00024
00025 Viewmode ViewmodeToVolumeCanvas(int vm)
00026 {
00027 for (int i = 0; i < 4; ++i)
00028 if (viewmodemap[i].value == vm) return viewmodemap[i].mode;
00029 return VM_SLICE_X;
00030 }
00031 }
00032
00033 VisLUFrame::VisLUFrame(wxWindow* parent) :
00034 VisLUFrameBase(parent)
00035 {
00036 SetExtraStyle(GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
00037
00038
00039 m_volcanvas = new VolumeCanvas(m_volcanvas_panel, wxID_ANY);
00040 m_volcanvas_sizer->Add(m_volcanvas, 1, wxEXPAND);
00041
00042 m_volcanvas_sizer->Layout();
00043
00044 m_viewmode = ViewmodeFromVolumeCanvas(m_volcanvas->GetViewmode());
00045
00046 m_slice = 50;
00047 m_rotx = m_roty = m_rotz = 0;
00048
00049
00050 m_viewmode_box->SetValidator(wxGenericValidator(&m_viewmode));
00051 m_slice_slider->SetValidator(wxGenericValidator(&m_slice));
00052 m_rotx_slider->SetValidator(wxGenericValidator(&m_rotx));
00053 m_roty_slider->SetValidator(wxGenericValidator(&m_roty));
00054 m_rotz_slider->SetValidator(wxGenericValidator(&m_rotz));
00055
00056
00057 TransferDataToWindow();
00058
00059 SyncUIState();
00060
00061
00062 Center(wxBOTH);
00063 }
00064
00065 void VisLUFrame::OnExit(wxCommandEvent& event)
00066 {
00067 Close();
00068 }
00069
00070 namespace {
00071 class ResolutionValidator : public wxTextValidator
00072 {
00073 public:
00074 ResolutionValidator(long *target, int min_value, int max_value)
00075 : wxTextValidator(wxFILTER_NUMERIC, &m_string_target)
00076 , m_target(target)
00077 , m_max_value(max_value)
00078 , m_min_value(min_value)
00079 , m_string_target(wxT(""))
00080 {
00081 m_string_target.sprintf(wxT("%d"), *target);
00082 }
00083
00084 bool TransferFromWindow()
00085 {
00086
00087 return (wxTextValidator::TransferFromWindow())?(m_string_target.ToLong(m_target)):(false);
00088 }
00089
00090 bool Validate(wxWindow *parent)
00091 {
00092 long temp_value;
00093
00094
00095 if(!wxTextValidator::Validate(parent)) return false;
00096
00097 if(!static_cast<wxTextCtrl *>(GetWindow())->GetValue().ToLong(&temp_value, 10)) return false;
00098
00099 if(temp_value > m_max_value || temp_value < m_min_value) return false;
00100
00101 return true;
00102 }
00103
00104 wxObject* Clone() const
00105 {
00106 return new ResolutionValidator(m_target, m_min_value, m_max_value);
00107 }
00108
00109 private:
00110 wxString m_string_target;
00111 long *m_target;
00112 int m_max_value;
00113 int m_min_value;
00114 };
00115 }
00116
00117 void VisLUFrame::OnSave(wxCommandEvent& event)
00118 {
00119 wxString caption = _("Save Screenshot");
00120 wxList image_handlers = wxImage::GetHandlers();
00121 wxImageHandler *current_handler = static_cast<wxImageHandler *>(image_handlers[0]);
00122 wxString wildcard = current_handler->GetName() + wxT(" (*.") + current_handler->GetExtension() + wxT(")|*.") + current_handler->GetExtension();
00123 int filter_index_png;
00124
00125 for(unsigned int i = 1; i < image_handlers.GetCount(); i++)
00126 {
00127 current_handler = static_cast<wxImageHandler *>(image_handlers[i]);
00128 wildcard.append(wxT("|") + current_handler->GetName() + wxT(" (*.") + current_handler->GetExtension() + wxT(")|*.") + current_handler->GetExtension());
00129 if(current_handler->GetExtension() == wxT("png"))
00130 {
00131 filter_index_png = i;
00132 }
00133 }
00134
00135 wxFileDialog dlg(this, caption, wxEmptyString, wxEmptyString, wildcard, wxSAVE);
00136
00137 GLint max_buffer_size;
00138 long screenshot_width = m_volcanvas->GetClientRect().GetSize().GetWidth();
00139 long screenshot_height = m_volcanvas->GetClientRect().GetSize().GetHeight();
00140
00141 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_buffer_size);
00142
00143 dlg.SetFilterIndex(filter_index_png);
00144
00145 if (dlg.ShowModal() == wxID_OK) {
00146 ScreenShotDialog settings_dlg(this);
00147
00148 settings_dlg.m_TB_width->SetValidator(
00149 ResolutionValidator(&screenshot_width, 100, max_buffer_size / 2));
00150 settings_dlg.m_TB_height->SetValidator(ResolutionValidator(&screenshot_height, 100, max_buffer_size / 2));
00151
00152 if (settings_dlg.ShowModal() == wxID_OK) {
00153
00154 wxString full_name = dlg.GetPath();
00155 if (full_name.rfind(wxT(".")) == -1) {
00156 full_name.append(wxT("."));
00157 full_name.append(static_cast<wxImageHandler *> (image_handlers[dlg.GetFilterIndex()])->GetExtension());
00158 }
00159 m_volcanvas->RenderToFile(full_name, screenshot_width, screenshot_height);
00160 }
00161 }
00162 }
00163
00164 void VisLUFrame::OnAbout(wxCommandEvent& event)
00165 {
00166 wxAboutDialogInfo info;
00167 info.SetVersion(wxT("0.0.0"));
00168 info.SetDescription(_("Volume visualisation tool for the VisLU lab course"));
00169 info.AddDeveloper(wxT("Markus Trenkwalder"));
00170 info.AddDeveloper(wxT("Stefan Kollmann"));
00171 wxAboutBox(info);
00172 }
00173
00174 namespace
00175 {
00176 struct TransferFunctionSamplerFromTraFuDialogData: public TransferFunctionSampler {
00177 Mapping_point_vector_t density_vector;
00178
00179 TransferFunctionSamplerFromTraFuDialogData(TraFuData &data)
00180 {
00181 density_vector = data.createDensityVector(4096);
00182 }
00183
00184 Color MapDensity(float density)
00185 {
00186 const int index = static_cast<int> (density * 4095);
00187 const Mapping_point_t &temp = density_vector[index];
00188 Color result;
00189 result.r = temp.m_colour.red / 255.0f;
00190 result.g = temp.m_colour.green / 255.0f;
00191 result.b = temp.m_colour.blue / 255.0f;
00192 result.a = temp.m_opacity;
00193 return result;
00194 }
00195 };
00196 }
00197
00198 void VisLUFrame::OnOpenTraFu(wxCommandEvent& event)
00199 {
00200 TraFuData old_data = m_trafu_data;
00201
00202 TraFuDialog dialog(this, &m_trafu_data, m_volcanvas->GetHistogramData());
00203 if (wxID_OK == dialog.ShowModal()) {
00204
00205 TransferFunctionSamplerFromTraFuDialogData tmp(m_trafu_data);
00206 m_volcanvas->UpdateTransferFunction(&tmp);
00207 } else {
00208 m_trafu_data = old_data;
00209 }
00210 }
00211
00212 namespace
00213 {
00214 void ShowLoadingError(wxWindow* parent, const wxString* info)
00215 {
00216 wxString message(_("Failed to load volume data."));
00217 if (info) message += _("\n\nReason:\n") + *info;
00218 wxMessageBox(message, _("Error"), wxOK | wxCENTER | wxICON_ERROR, parent);
00219 }
00220 }
00221
00222 void VisLUFrame::OnOpen(wxCommandEvent& event)
00223 {
00224 wxString caption = _("Open Data File");
00225 wxString wildcard = _("Volume Data Files (*.dat)|*.dat|All Files (*.*)|*.*");
00226 wxFileDialog dlg(this, caption, wxEmptyString, wxEmptyString, wildcard, wxOPEN | wxFILE_MUST_EXIST);
00227
00228 if (dlg.ShowModal() == wxID_OK) {
00229 try {
00230 m_volcanvas->OpenFile(dlg.GetPath().fn_str());
00231 TransferFunctionSamplerFromTraFuDialogData tmp(m_trafu_data);
00232 m_volcanvas->UpdateTransferFunction(&tmp);
00233 } catch (const std::exception &e) {
00234 wxString info = wxString::FromAscii(e.what());
00235 ShowLoadingError(this, &info);
00236 } catch (...) {
00237 ShowLoadingError(this, 0);
00238 }
00239 }
00240
00241 SyncUIState();
00242 }
00243
00244 void VisLUFrame::SyncUIState()
00245 {
00246 TransferDataFromWindow();
00247
00248
00249 int size;
00250 switch (m_viewmode) {
00251 case 1:
00252 size = m_volcanvas->GetSizeX();
00253 break;
00254 case 2:
00255 size = m_volcanvas->GetSizeY();
00256 break;
00257 case 3:
00258 size = m_volcanvas->GetSizeZ();
00259 break;
00260 default:
00261 size = 100;
00262 break;
00263 }
00264
00265 if (size == 0) size = 100;
00266 m_slice_slider->SetMax(size);
00267
00268 m_volcanvas->SetViewmode(ViewmodeToVolumeCanvas(m_viewmode));
00269 m_volcanvas->SetSlice(m_slice);
00270 m_volcanvas->Set3dOrientation(m_rotx, m_roty, m_rotz);
00271 m_volcanvas->Refresh();
00272
00273 TransferDataToWindow();
00274 }
00275
00276 void VisLUFrame::OnViewmodeChanged(wxCommandEvent& event)
00277 {
00278 SyncUIState();
00279 }
00280
00281 void VisLUFrame::OnSliceChanged(wxScrollEvent& event)
00282 {
00283 SyncUIState();
00284 }
00285
00286 void VisLUFrame::OnOrientationChanged(wxScrollEvent& event)
00287 {
00288 SyncUIState();
00289 }
00290
00291 void VisLUFrame::OnVolcanvasEraseBackground(wxEraseEvent& event)
00292 {
00293
00294 }
00295
00296 void VisLUFrame::OnTraFuChanged()
00297 {
00298 TransferFunctionSamplerFromTraFuDialogData tmp(m_trafu_data);
00299 m_volcanvas->UpdateTransferFunction(&tmp);
00300 }