00001 #include "flowvis_frame.h"
00002 #include "trafu_dialog.h"
00003
00004 #include <wx/filedlg.h>
00005 #include <wx/image.h>
00006 #include <wx/valgen.h>
00007 #include <wx/spinctrl.h>
00008 #include <wx/aboutdlg.h>
00009 #include <wx/msgdlg.h>
00010 #include <wx/valtext.h>
00011
00012 #include <stdexcept>
00013
00014 namespace
00015 {
00016 struct TransferFunctionSamplerFromTraFuDialogData: public TransferFunctionSampler {
00017 Mapping_point_vector_t density_vector;
00018
00019 TransferFunctionSamplerFromTraFuDialogData(TraFuData &data)
00020 {
00021 density_vector = data.createDensityVector(4096);
00022 }
00023
00024 Color MapDensity(float density)
00025 {
00026 const int index = static_cast<int> (density * 4095);
00027 const Mapping_point_t &temp = density_vector[index];
00028 Color result;
00029 result.r = temp.m_colour.red / 255.0f;
00030 result.g = temp.m_colour.green / 255.0f;
00031 result.b = temp.m_colour.blue / 255.0f;
00032 result.a = temp.m_opacity;
00033 return result;
00034 }
00035 };
00036 }
00037
00038 FlowVisFrame::FlowVisFrame(wxWindow* parent)
00039 : FlowVisFrameBase(parent)
00040 , m_data(0)
00041 {
00042 SyncUI();
00043
00044
00045 try
00046 {
00047 m_flowcanvas = new FlowVisCanvas(m_flowcanvas_panel, wxID_ANY);
00048 m_flowcanvas_sizer->Add(m_flowcanvas, 1, wxEXPAND);
00049
00050 m_flowcanvas_sizer->Layout();
00051
00052 TransferSLPlotSettings();
00053 TransferCalcSettings();
00054 }catch(std::runtime_error &e)
00055 {
00056
00057 wxMessageBox(wxString::FromAscii((e.what())), _T("Critical Error"), wxOK);
00058 Close();
00059 }
00060 }
00061
00062 void FlowVisFrame::OnExit(wxCommandEvent &event)
00063 {
00064 Close();
00065 }
00066
00067 void FlowVisFrame::OnOpen(wxCommandEvent &event)
00068 {
00069 wxString caption = _("Choose Grid File");
00070 wxString wildcard = _("Flowdata Grid Files (*.gri)|*.gri|All Files (*.*)|*.*");
00071 wxFileDialog dlg(this, caption, wxEmptyString, wxEmptyString, wildcard, wxOPEN | wxFILE_MUST_EXIST);
00072
00073 if(dlg.ShowModal() == wxID_OK)
00074 {
00075 try
00076 {
00077 m_data = std::auto_ptr<FlowVisData>(new FlowVisData());
00078
00079 wxString sole_name = dlg.GetFilename();
00080 m_data->LoadFromFile(dlg.GetPath().fn_str());
00081
00082 m_trafu_datas.clear();
00083 for(int i = 0; i < m_data->GetNrSets(); i++)
00084 {
00085 m_trafu_datas.push_back(TraFuData());
00086 }
00087
00088 SyncUI();
00089
00090 m_flowcanvas->SetData(m_data);
00091
00092 OnTraFuChanged();
00093 }catch(...)
00094 {
00095
00096 }
00097 }
00098 }
00099
00100 void FlowVisFrame::SyncUI()
00101 {
00102 if(m_trafu_datas.size())
00103 {
00104 m_BG_TF->Enable(true);
00105 m_B_apply_settings->Enable(true);
00106 }else
00107 {
00108 m_BG_TF->Enable(false);
00109 m_B_apply_settings->Enable(false);
00110 }
00111
00112 m_BG_sets->Clear();
00113
00114 int i = 0;
00115
00116 for(; m_data.get() && i < m_data->GetNrSets(); i++)
00117 {
00118 wxString entry(wxT("Data - "));
00119 entry << i;
00120 m_BG_sets->Append(entry);
00121 }
00122
00123 if(i)
00124 {
00125 m_BG_sets->Enable(true);
00126 m_BG_sets->SetSelection(0);
00127 m_current_set = 0;
00128 }else
00129 {
00130 m_BG_sets->Enable(false);
00131 }
00132 }
00133
00134 void FlowVisFrame::OnBGOpenTraFu(wxCommandEvent& event)
00135 {
00136 TraFuData old_data = m_trafu_datas[m_current_set];
00137
00138 TraFuDialog dialog(this, &(m_trafu_datas[m_current_set]), 0);
00139 if (wxID_OK == dialog.ShowModal()) {
00140
00141 TransferFunctionSamplerFromTraFuDialogData tmp(m_trafu_datas[m_current_set]);
00142
00143 } else {
00144 m_trafu_datas[m_current_set] = old_data;
00145 }
00146 }
00147
00148 void FlowVisFrame::OnBGComboChange(wxCommandEvent& event)
00149 {
00150 m_current_set = m_BG_sets->GetSelection();
00151 m_flowcanvas->SetBackgroundSet(m_BG_sets->GetSelection());
00152 OnTraFuChanged();
00153 }
00154
00155 void FlowVisFrame::OnTraFuChanged()
00156 {
00157 TransferFunctionSamplerFromTraFuDialogData tmp(m_trafu_datas[m_current_set]);
00158 m_flowcanvas->UpdateTransferFunction(&tmp, m_current_set);
00159 }
00160
00161 void FlowVisFrame::OnChangeNrArrows(wxSpinEvent& event)
00162 {
00163 m_flowcanvas->SetArrows(m_arrows_x_spin->GetValue(), m_arrows_y_spin->GetValue());
00164 }
00165
00166 void FlowVisFrame::OnArrowOpenTraFu(wxCommandEvent& event)
00167 {
00168 }
00169
00170 void FlowVisFrame::OnPlotSettingsChange(wxCommandEvent& event)
00171 {
00172 m_flowcanvas->SetArrowPlot(m_CB_plot_arrows->GetValue());
00173 m_flowcanvas->SetBackgroundPlot(m_CB_plot_background->GetValue());
00174 }
00175
00176 void FlowVisFrame::OnAbout(wxCommandEvent& event)
00177 {
00178 wxAboutDialogInfo info;
00179 info.SetVersion(wxT("1.0.0"));
00180 info.SetDescription(_("Flow visualisation tool for the VisLU lab course"));
00181 info.AddDeveloper(wxT("Markus Trenkwalder"));
00182 info.AddDeveloper(wxT("Stefan Kollmann"));
00183 wxAboutBox(info);
00184 }
00185
00186 void FlowVisFrame::OnGlyphDensitChanged(wxScrollEvent& event)
00187 {
00188 TransferSLPlotSettings();
00189 m_flowcanvas->Refresh();
00190 }
00191
00192 void FlowVisFrame::OnSLColorChange(wxColourPickerEvent& event)
00193 {
00194 TransferSLPlotSettings();
00195 m_flowcanvas->Refresh();
00196 }
00197
00198 void FlowVisFrame::OnSLPlotSettingsChange(wxCommandEvent& event)
00199 {
00200 TransferSLPlotSettings();
00201 m_flowcanvas->Refresh();
00202 }
00203
00204 void FlowVisFrame::TransferSLPlotSettings()
00205 {
00206 m_flowcanvas->SetStreamlinePlot(m_CB_plot_streamlines->GetValue());
00207 m_flowcanvas->SetLineColor(m_CC_streamline_color->GetColour());
00208 m_flowcanvas->SetLineTapering(m_CB_plot_tapering->GetValue());
00209 m_flowcanvas->SetLineGlyphs(m_CB_plot_glyphs->GetValue());
00210 m_flowcanvas->SetGlyphDensity(m_SL_gyph_density->GetValue());
00211 }
00212
00213 void FlowVisFrame::OnApplyCalcSettings(wxCommandEvent& event)
00214 {
00215 TransferCalcSettings();
00216 m_flowcanvas->Prepare_Streamlines();
00217 m_flowcanvas->Refresh();
00218 }
00219
00220 void FlowVisFrame::TransferCalcSettings()
00221 {
00222 m_flowcanvas->SetIntegType(m_C_streamline_interpolation->GetSelection());
00223 m_flowcanvas->SetMaxIter(m_SL_maxiter->GetValue());
00224 m_flowcanvas->SetDtest(m_SP_dtest->GetValue() / 1024.0f);
00225 m_flowcanvas->SetDsep(m_SP_dsep->GetValue() / 1024.0f);
00226 m_flowcanvas->SetStepSize(m_SP_stepsize->GetValue() / 1024.0f);
00227 }
00228
00229 namespace {
00230 class ResolutionValidator : public wxTextValidator
00231 {
00232 public:
00233 ResolutionValidator(long *target, int min_value, int max_value)
00234 : wxTextValidator(wxFILTER_NUMERIC, &m_string_target)
00235 , m_target(target)
00236 , m_max_value(max_value)
00237 , m_min_value(min_value)
00238 , m_string_target(wxT(""))
00239 {
00240 m_string_target.sprintf(wxT("%d"), *target);
00241 }
00242
00243 bool TransferFromWindow()
00244 {
00245
00246 return (wxTextValidator::TransferFromWindow())?(m_string_target.ToLong(m_target)):(false);
00247 }
00248
00249 bool Validate(wxWindow *parent)
00250 {
00251 long temp_value;
00252
00253
00254 if(!wxTextValidator::Validate(parent)) return false;
00255
00256 if(!static_cast<wxTextCtrl *>(GetWindow())->GetValue().ToLong(&temp_value, 10)) return false;
00257
00258 if(temp_value > m_max_value || temp_value < m_min_value) return false;
00259
00260 return true;
00261 }
00262
00263 wxObject* Clone() const
00264 {
00265 return new ResolutionValidator(m_target, m_min_value, m_max_value);
00266 }
00267
00268 private:
00269 wxString m_string_target;
00270 long *m_target;
00271 int m_max_value;
00272 int m_min_value;
00273 };
00274 }
00275
00276 void FlowVisFrame::OnSave(wxCommandEvent& event)
00277 {
00278 wxString caption = _("Save Screenshot");
00279 wxList image_handlers = wxImage::GetHandlers();
00280 wxImageHandler *current_handler = static_cast<wxImageHandler *>(image_handlers[0]);
00281 wxString wildcard = current_handler->GetName() + wxT(" (*.") + current_handler->GetExtension() + wxT(")|*.") + current_handler->GetExtension();
00282 int filter_index_png;
00283
00284 for(unsigned int i = 1; i < image_handlers.GetCount(); i++)
00285 {
00286 current_handler = static_cast<wxImageHandler *>(image_handlers[i]);
00287 wildcard.append(wxT("|") + current_handler->GetName() + wxT(" (*.") + current_handler->GetExtension() + wxT(")|*.") + current_handler->GetExtension());
00288 if(current_handler->GetExtension() == wxT("png"))
00289 {
00290 filter_index_png = i;
00291 }
00292 }
00293
00294 wxFileDialog dlg(this, caption, wxEmptyString, wxEmptyString, wildcard, wxSAVE);
00295
00296 GLint max_buffer_size;
00297 long screenshot_width = m_flowcanvas->GetClientRect().GetSize().GetWidth();
00298 long screenshot_height = m_flowcanvas->GetClientRect().GetSize().GetHeight();
00299
00300 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_buffer_size);
00301
00302 dlg.SetFilterIndex(filter_index_png);
00303
00304 if (dlg.ShowModal() == wxID_OK) {
00305 ScreenShotDialog settings_dlg(this);
00306
00307 settings_dlg.m_TB_width->SetValidator(
00308 ResolutionValidator(&screenshot_width, 100, max_buffer_size));
00309 settings_dlg.m_TB_height->SetValidator(ResolutionValidator(&screenshot_height, 100, max_buffer_size));
00310
00311 if (settings_dlg.ShowModal() == wxID_OK) {
00312
00313 wxString full_name = dlg.GetPath();
00314 if (full_name.rfind(wxT(".")) == -1) {
00315 full_name.append(wxT("."));
00316 full_name.append(static_cast<wxImageHandler *> (image_handlers[dlg.GetFilterIndex()])->GetExtension());
00317 }
00318 m_flowcanvas->RenderToFile(full_name, screenshot_width, screenshot_height);
00319 }
00320 }
00321 }