Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleContextWx.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 /**
27  @example ExampleContextWx.cpp
28  @relates ContextWX, GLProjectionParametersPerspective, SceneOpenSceneGraph
29  @brief Example for usage ContextWX, GLProjections and Scenes
30  @ingroup g_examples
31  @ingroup g_glviewer
32  @author MIP, ischiller 02/2010
33 */
34 
35 #include <Base/Common/BIASpragmaStart.hh>
36 #include <wx/wx.h>
37 #include <wx/aboutdlg.h>
38 #include <wx/filename.h>
39 #include <wx/artprov.h>
40 #include <Base/Common/BIASpragmaEnd.hh>
41 
42 #include <Base/Image/Image.hh>
43 #include <Base/Image/ImageIO.hh>
44 #include <Base/Common/FileHandling.hh>
45 #include <Gui/StringConv.hh>
46 #include <GLviewer/ContextWX.hh>
47 #include <GLviewer/Scenes/SceneBGImage.hh>
48 #ifdef BIAS_HAVE_OPENSCENEGRAPH
49 #include <GLviewer/Scenes/SceneOpenSceneGraph.hh>
50 #endif
51 #include <GLviewer/GLProjectionParametersPerspective.hh>
52 #include <GLviewer/Controller/DistanceMeasureControl.hh>
53 
54 using namespace BIAS;
55 using namespace std;
56 
57 /////////////////////////////////////
58 ////////// the window //////////
59 /////////////////////////////////////
60 /**
61  * \cond HIDDEN_SYMBOLS
62  */
63 class CWxFrame : public wxFrame
64 {
65 
66 public:
67 
68  CWxFrame(wxWindow *parent, const wxString& title);
69 
70  void OnOpen(wxCommandEvent &event);
71  void OnQuit(wxCommandEvent &event);
72  void OnScreenshot(wxCommandEvent& event);
73  void OnViewSize(wxCommandEvent& event);
74  void OnAbout(wxCommandEvent &event);
75  void OnScreenInfo(wxCommandEvent &event);
76 
77  void OnResize(wxSizeEvent &event);
78 
79  void LateInit();
80 
81 protected:
83  ContextWX* DummyContext_;
84  ContextWX* Context_;
85 #ifdef BIAS_HAVE_OPENSCENEGRAPH
86  SceneOpenSceneGraph* Scene_;
87 #endif
88  SceneBGImage BGImage_;
89  Image<unsigned char> LogoBG_;
91 
92  bool SizeLocked_;
93 
94  enum {
95  ID_Whatever = wxID_HIGHEST + 42,
96  ID_Screenshot,
97  ID_VS_Free,
98  ID_VS_640,
99  ID_VS_800,
100  ID_VS_16_9,
101  ID_VS_16_10,
102  ID_ScreenInfo
103  };
104 
105 private:
106 
107  void DumpSizes_();
108  void FitToImageSize_();
109 
110  wxMenuBar* Menubar_;
111  wxToolBar* Toolbar_;
112  wxStatusBar* Statusbar_;
113  DECLARE_EVENT_TABLE()
114 
115 };
116 /** \endcond */
117 
118 BEGIN_EVENT_TABLE(CWxFrame, wxFrame)
119  EVT_MENU(wxID_OPEN, CWxFrame::OnOpen)
120  EVT_MENU(wxID_EXIT, CWxFrame::OnQuit)
121  EVT_MENU(wxID_ABOUT, CWxFrame::OnAbout)
122  EVT_MENU(ID_Screenshot, CWxFrame::OnScreenshot)
123  EVT_MENU(ID_VS_Free, CWxFrame::OnViewSize)
124  EVT_MENU(ID_VS_640, CWxFrame::OnViewSize)
125  EVT_MENU(ID_VS_800, CWxFrame::OnViewSize)
126  EVT_MENU(ID_VS_16_9, CWxFrame::OnViewSize)
127  EVT_MENU(ID_VS_16_10, CWxFrame::OnViewSize)
128  EVT_MENU(ID_ScreenInfo, CWxFrame::OnScreenInfo)
129  EVT_SIZE(CWxFrame::OnResize)
130 END_EVENT_TABLE()
131 
132 CWxFrame::CWxFrame(wxWindow *parent, const wxString& title)
133 : wxFrame(parent, wxID_ANY, title),
134  Context_(NULL), Proj_(NULL),
135  SizeLocked_(false)
136 {
137 #ifdef BIAS_HAVE_OPENSCENEGRAPH
138  Scene_ = NULL;
139 #endif
140  int ContextAttribs[] = { WX_GL_RGBA,
141  WX_GL_LEVEL, 0,
142  WX_GL_MIN_RED, 1,
143  WX_GL_MIN_GREEN, 1,
144  WX_GL_MIN_BLUE, 1,
145  WX_GL_MIN_ALPHA, 1,
146  WX_GL_DEPTH_SIZE, 24,
147  WX_GL_STENCIL_SIZE, 8,
148  WX_GL_DOUBLEBUFFER, 0 };
149  DummyContext_ = new ContextWX( this, wxID_ANY,
150  wxDefaultPosition, wxSize(640, 480), 0,
151  wxT("GLCanvas"),ContextAttribs);
152  DummyContext_->SetBlending(false);
153  DummyContext_->SetBackfaceCulling(false);
154  DummyContext_->SetMinSize( wxSize( 320,240 ) );
155 
156  // create a status bar
157  Statusbar_ = this->CreateStatusBar( 2, wxST_SIZEGRIP, wxID_ANY );
158  const int numFields = 2;
159  Statusbar_->SetFieldsCount(numFields);
160  const int widths[numFields] = { -1, 170 };
161  Statusbar_->SetStatusWidths(numFields, widths);
162 
163  // create a tool bar
164  Toolbar_ = this->CreateToolBar( wxTB_HORIZONTAL, wxID_ANY );
165  Toolbar_->SetToolBitmapSize( wxSize( 24,24 ) );
166  Toolbar_->SetToolSeparation( 0 );
167  Toolbar_->SetToolPacking( 0 );
168  Toolbar_->AddTool( ID_ScreenInfo, wxT("Screen Info"),
169  wxArtProvider::GetIcon(wxART_INFORMATION,wxART_TOOLBAR) );
170  Toolbar_->AddTool( wxID_OPEN, wxT("Open File"),
171  wxArtProvider::GetIcon(wxART_FILE_OPEN ,wxART_TOOLBAR) );
172 
173  Toolbar_->Realize();
174 
175  // create a menu bar
176  wxMenu *menuFile = new wxMenu;
177  menuFile->Append(wxID_OPEN);
178  menuFile->AppendSeparator();
179  menuFile->Append(wxID_EXIT);
180  wxMenu *menuEdit = new wxMenu;
181  menuEdit->Append(ID_Screenshot, wxString(wxT("&Screenshot")) + wxT('\t') + wxT("F3"));
182  wxMenu *menuView = new wxMenu;
183  menuView->AppendRadioItem(ID_VS_Free, wxString(wxT("View Size &Free")) + wxT('\t') + wxT("CTRL-SHIFT-0"));
184  menuView->AppendRadioItem(ID_VS_640, wxString(wxT("View Size 4:3 &small")) + wxT('\t') + wxT("CTRL-SHIFT-1"));
185  menuView->AppendRadioItem(ID_VS_800, wxString(wxT("View Size 4:3 &medium")) + wxT('\t') + wxT("CTRL-SHIFT-2"));
186  menuView->AppendRadioItem(ID_VS_16_9, wxString(wxT("View Size 16:&9 medium")) + wxT('\t') + wxT("CTRL-SHIFT-3"));
187  menuView->AppendRadioItem(ID_VS_16_10, wxString(wxT("View Size 16:&10 medium")) + wxT('\t') + wxT("CTRL-SHIFT-4"));
188  wxMenu *menuHelp = new wxMenu;
189  menuHelp->Append(wxID_ABOUT);
190  Menubar_ = new wxMenuBar;
191  Menubar_->Append(menuFile, wxT("&File"));
192  Menubar_->Append(menuEdit, wxT("&Edit"));
193  Menubar_->Append(menuView, wxT("&View"));
194  Menubar_->Append(menuHelp, wxT("&Help"));
195 
196  SetMenuBar(Menubar_);
197  wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
198  mainSizer->Add(Context_, 1, wxEXPAND|wxALL|wxALIGN_CENTRE, 0);
199 
200  /// this is the problem
201  //SetMinSize(wxSize(400,390));
202 
203  SetSizer(mainSizer);
204  mainSizer->Fit(this);
205  Layout();
206 
207  Proj_ = new GLProjectionParametersPerspective( /*offscreen*/);
208 }
209 
210 void CWxFrame::
211 LateInit()
212 {
213  Context_ = DummyContext_;
214  //Context_->AppendAdditionalListener(&Handler_);
215  LogoBG_.Init(400, 300, 3);
216  LogoBG_.FillImageWithConstValue(120);
217  BGImage_.SetImage(LogoBG_);
218  Context_->MakeGLContextCurrent();
219  Context_->SetBlending(false);
220 
221 
222  // use special background image mode, which bypasses also fisheye rendering
223  // doesn't seem to work with distortion mapping
224  Context_->SetBackgroundImageScene(&BGImage_);
225 #ifdef BIAS_HAVE_OPENSCENEGRAPH
226  Scene_ = new SceneOpenSceneGraph;
227  BIASASSERT(Scene_);
228  if(Scene_->Init()!=0)
229  {
230  cerr<<"Scene_ init failed !!!"<<endl;
231  }
232  Scene_->SetActive(false);
233  Scene_->HeadlightSwitch(true);
234  Context_->AppendScene(Scene_);
235 
236 #else
237  BIASWARN("Need OpenSceneGraph to show something")
238 #endif
239 
240  Proj_->SetSimplePerspectiveCam(40.0);
241  Proj_->SetAutoReshapeBehaviour(GLProjectionParametersBase::AutoRescaleSimple);
242  Context_->SetGLProjectionParametersInterface(Proj_);
243  Context_->SetControl(&control_);
244  //DistanceMeaseureControl is also derived from Scenebase and draws itself
245  Context_->AppendScene(&control_);
246 
247  Context_->PrintGLStatus();
248  Context_->InitializationComplete();
249 
250  Context_->SetAutoClipping(true);
251  Context_->SetAutoClipMinZNear(0.1);
252 
253  // background color (yellow: 1.0f, 1.0f, 0.0f, 0.0f)
254  Vector4<float> bg(1.0f, 1.0f, 0.0f, 0.0f);
255  Context_->SetClearColor(bg);
256 
257 
258  FitToImageSize_();
259 }
260 
261 
262 
263 void CWxFrame::
264 OnResize(wxSizeEvent &event)
265 {
266  cout << "size event: window size \t("
267  << GetSize().GetWidth() << " x " << GetSize().GetHeight() << ")\n";
268  event.Skip();
269 }
270 
271 
272 void CWxFrame::
273 OnOpen(wxCommandEvent &event)
274 {
275 #ifdef BIAS_HAVE_OPENSCENEGRAPH
276  wxString fileName;
277  wxFileDialog
278  dialog(
279  this,
280  wxT("Load Model"),
281  wxT(""),
282  wxT(""),
283  wxT("Model files (*.wrl;*.dae;*.osg;*.3ds;)|*.wrl;*.dae;*.osg;*.3ds;|All files (*.*)|*.*"),
284  wxFD_OPEN);
285  int ret = dialog.ShowModal();
286  if (ret == wxID_OK) {
287  ret = Scene_->AppendSubTreeFromFile(WxToAscii(dialog.GetPath()));
288  }
289  if (ret != 0){
290  stringstream text;
291  text<<"Error, model could not be loaded";
292  wxMessageBox(AsciiToWx(text.str()),wxT("Error"), wxOK | wxICON_ERROR, this);
293  }
294  else{
295  BIAS::Vector3<double> CameraCenter, radius, SceneCenter;
296  if (!Context_->GetSceneCenter(SceneCenter, radius))
297  BIASERR("could not retrieve bounding box from scene");
298  // move 10% outwards
299  CameraCenter = SceneCenter + 1.1 * radius;
300  cout<<"using scene center "<<SceneCenter<<" and new camera center "
301  <<CameraCenter <<endl;
302  // set point of interest only if not equal to camera center
303  if ((CameraCenter-SceneCenter).NormL2()>0.001) {
304  Proj_->GetMyselfAsProjectionParameterBase()->SetC(CameraCenter);
305  control_.SetPointOfInterest(SceneCenter);
306  } else {
307  cerr<<"could not set poi, empty scene ?"<<endl;
308  }
309  Context_->Refresh();
310  }
311 #else
312  stringstream text;
313  text<<"Error, BIAS does not have OpenSceneGraph to load models!";
314  wxMessageBox(AsciiToWx(text.str()),wxT("Error"), wxOK | wxICON_ERROR, this);
315 #endif
316  event.Skip();
317 }
318 
319 void CWxFrame::
320 OnQuit(wxCommandEvent &event)
321 {
322  Close();
323 }
324 
325 void CWxFrame::
326 OnViewSize(wxCommandEvent& event)
327 {
328  FitToImageSize_();
329 }
330 
331 void CWxFrame::
332 OnScreenInfo(wxCommandEvent &event)
333 {
334  BIASASSERT(Context_);
335  BIASASSERT(Proj_);
337  Context_->MakeGLContextCurrent();
338  Proj_->GetImage(shot);
339  unsigned w,h;
340  Proj_->GetImageSize(w, h);
341 
342  wxString msg = wxT("Context size is ");
343  msg << Context_->GetSize().GetWidth() << wxT(" x ")
344  << Context_->GetSize().GetHeight();
345  msg << wxT("\n") << wxT("Projection size is ");
346  msg << w << wxT(" x ") << h;
347  msg << wxT("\n") << wxT("Screenshot size will be ");
348  msg << shot.GetWidth() << wxT(" x ") << shot.GetHeight();
349 
350  wxMessageBox(msg, wxT("Example ContextWX - Screen Info"),
351  wxOK | wxICON_INFORMATION, this);
352 
353 }
354 
355 void CWxFrame::
356 OnScreenshot(wxCommandEvent& event)
357 {
358  BIASASSERT(Context_);
359 
361  Context_->MakeGLContextCurrent();
362  Proj_->GetImage(shot);
363 
364  wxFileDialog dlg(this, _("Example ContextWX - Save Screenshot"),
365  wxGetCwd(), wxT("ContextScreenshot"),
366  _("PNG (*.png)|*.png|JPEG (*.jpg)|*.jpg"),
367  wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxFD_CHANGE_DIR);
368  if ( dlg.ShowModal() != wxID_OK) return;
369 
370  wxFileName fname( dlg.GetPath() );
371 
372  if ( !fname.HasExt() ) {
373  int idx = dlg.GetFilterIndex();
374  switch (idx) {
375  case 1:
376  fname.SetExt(_("jpg"));
377  break;
378  default:
379  fname.SetExt(_("png"));
380  break;
381  }
382  }
383 
384  int res = -1;
385  if ( fname.GetExt() == wxT("jpg") ) {
386  res = ImageIO::Save(WxToFilenames(fname.GetFullPath()), shot, ImageIO::FF_jpg);
387  }
388  if ( fname.GetExt() == wxT("png") ) {
389  res = ImageIO::Save(WxToFilenames(fname.GetFullPath()), shot, ImageIO::FF_png);
390  }
391  if ( res != 0 ) {
392  wxMessageBox(wxT("Saving screenshot failed!"), wxT("Error"),
393  wxOK | wxICON_ERROR, this);
394  }
395 }
396 
397 
398 void CWxFrame::
399 OnAbout(wxCommandEvent &event)
400 {
401  wxString desc;
402  desc << wxT(" This example is part of the\n");
403  desc << wxT(" BIAS library (Basic ImageAlgorithmS)\n");
404  wxString lic = wxT("BIAS is free software; you can redistribute it and/or modify\n \
405 it under the terms of the GNU Lesser General Public Licence as published by\n \
406 the Free Software Foundation; either version 2.1 of the Licence, or\n \
407 (at your option) any later version.\n \
408 \n \
409 BIAS is distributed in the hope that it will be useful,\n \
410 but WITHOUT ANY WARRANTY; without even the implied warranty of\n \
411 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n \
412 GNU Lesser General Public Licence for more details.\n \
413 \n \
414 You should have received a copy of the GNU Lesser General Public Licence\n \
415 along with BIAS; if not, write to the Free Software\n \
416 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n");
417 
418  wxAboutDialogInfo aboutdlg;
419  aboutdlg.SetDescription( desc );
420  aboutdlg.SetLicence( lic );
421  aboutdlg.SetCopyright( wxT("Copyright (C) 2003-2010\n \
422  Multimediale Systeme der Informationsverarbeitung\n \
423  Institut fuer Informatik\n \
424  Christian-Albrechts-Universitaet Kiel") );
425  aboutdlg.SetWebSite( wxT("http://www.mip.informatik.uni-kiel.de/") );
426 
427  wxAboutBox( aboutdlg );
428 }
429 
430 
431 void CWxFrame::
432 DumpSizes_()
433 {
434  static unsigned run = 0;
435  cout << "\n****** loads of sizes (no. " << run++ << ") *****\n";
436  cout << "size locked? " << boolalpha << SizeLocked_ << endl;
437  cout << "window size \t(" << GetSize().GetWidth() << " x " << GetSize().GetHeight() << ")\n";
438  cout << "client size \t(" << GetClientSize().GetWidth() << " x " << GetClientSize().GetHeight() << ")\n";
439  cout << "menubar size \t(" << Menubar_->GetSize().GetWidth() << " x " << Menubar_->GetSize().GetHeight() << ")\n";
440  cout << "toolbar size \t(" << Toolbar_->GetSize().GetWidth() << " x " << Toolbar_->GetSize().GetHeight() << ")\n";
441  cout << "statusbar size \t(" << Statusbar_->GetSize().GetWidth() << " x " << Statusbar_->GetSize().GetHeight() << ")\n";
442  cout << "context size \t(" << Context_->GetSize().GetWidth() << " x " << Context_->GetSize().GetHeight() << ")\n";
443  Context_->MakeGLContextCurrent();
444  Context_->Render();
445  if (Proj_ != NULL) {
446  unsigned w,h;
447  Proj_->GetImageSize(w,h);
448  cout << "projection image \t(" << w << " x " << h << ")\n";
449  }
451  Context_->GetImage(img);
452  cout << "context image \t(" << img.GetWidth() << " x " << img.GetHeight() << ")\n";
453 
454 }
455 
456 
457 void CWxFrame::
458 FitToImageSize_()
459 {
460  cout << "++++ fitting ++++" << endl;
461  BIASASSERT(Context_);
462  DumpSizes_();
463  //wxSize windowSize = this->GetSize();
464  //wxSize clientSize = this->GetClientSize();
465  wxSize contextSize = Context_->GetSize();
466  SizeLocked_ = false;
467  //int barsHeight = 0; barsHeight = Menubar_->GetSize().GetHeight() + Toolbar_->GetSize().GetHeight()
468  // + Statusbar_->GetSize().GetHeight();
469 
470 
471  if ( Menubar_->IsChecked(ID_VS_640) ) {
472  SizeLocked_ = true;
473  contextSize.Set(640, 480);
474  //clientSize.Set(640, 480);
475  }
476 
477  if ( Menubar_->IsChecked(ID_VS_800) ) {
478  SizeLocked_ = true;
479  contextSize.Set(800, 600);
480  //clientSize.Set(800, 600);
481  }
482 
483  if ( Menubar_->IsChecked(ID_VS_16_9) ) {
484  SizeLocked_ = true;
485  contextSize.Set(800, 450);
486  //clientSize.Set(800, 450);
487  }
488 
489  if ( Menubar_->IsChecked(ID_VS_16_10) ) {
490  SizeLocked_ = true;
491  contextSize.Set(800, 500);
492  //clientSize.Set(800, 500);
493  }
494 
495  if ( Menubar_->IsChecked(ID_VS_Free) ) {
496  SizeLocked_ = false;
497  }
498 
499  if ( SizeLocked_ ) {
500  Context_->SetSize(contextSize);
501  cout << "setting context size \t(" << Context_->GetSize().GetWidth() << " x " << Context_->GetSize().GetHeight() << ")\n";
502  this->SetClientSize(contextSize);
503  }
504  else {
505  wxSize minContextSize = Context_->GetMinSize();
506  if ( contextSize.GetWidth() < minContextSize.GetWidth()
507  || contextSize.GetHeight() < minContextSize.GetHeight() ) {
508  contextSize = minContextSize;
509  Context_->SetSize(contextSize);
510  }
511  this->SetClientSize(contextSize);
512  }
513 
514  Fit();
515  cout << "fit: context size \t(" << Context_->GetSize().GetWidth() << " x " << Context_->GetSize().GetHeight() << ")\n";
516  //Layout();
517  //Update();
518  //DumpSizes_();
519  wxString msg = wxT("Context size is ");
520  msg << Context_->GetSize().GetWidth() << wxT(" x ")
521  << Context_->GetSize().GetHeight();
522  Statusbar_->SetStatusText(msg);
523 }
524 
525 
526 ////////////////////////////////////////
527 ////////// main routine //////////
528 ////////////////////////////////////////
529 /** \cond HIDDEN_SYMBOLS */
530 class CWxApp : public wxApp
531 {
532 
533 public:
534  bool OnInit();
535 
536 protected:
537 
538 };
539 /** \endcond */
540 
541 bool CWxApp::OnInit()
542 {
543  wxInitAllImageHandlers();
544 
545 
546  CWxFrame* mainFrame =
547  new CWxFrame(NULL, wxT("Example ContextWX"));
548  mainFrame->Show();
549 
550  mainFrame->LateInit();
551 
552  return true;
553 
554 }
555 
556 IMPLEMENT_APP(CWxApp)
557 
class for distance measurements in 3d model, derives from TrackballControl and SceneBase ...
wxString AsciiToWx(const char *thestring)
Converts a C string to a wxString.
Definition: StringConv.hh:32
Scene that renders a background image behind all other scenes.
Definition: SceneBGImage.hh:42
unsigned int GetWidth() const
Definition: ImageBase.hh:312
Context implementation for wxWidgets.
Definition: ContextWX.hh:31
unsigned int GetHeight() const
Definition: ImageBase.hh:319
Implements narrow access to OpenSceneGraph.
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
Definition: ImageIO.cpp:725
rescale internal projection parameters preeerving aspectration but use non-integer values...
class for rendering with projection parameters of ProjectionParametersPerspective ...