MRPT  1.9.9
CDisplayWindow3D.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "gui-precomp.h" // Precompiled headers
11 
12 #include <mrpt/config.h>
13 
15 #include <mrpt/img/CImage.h>
16 #include <mrpt/system/CTicTac.h>
17 
18 #include <mrpt/gui/WxSubsystem.h>
19 #include <mrpt/gui/WxUtils.h>
20 
21 #if MRPT_HAS_OPENGL_GLUT
22 #ifdef _WIN32
23 // Windows:
24 #include <windows.h>
25 #endif
26 
27 #ifdef __APPLE__
28 #include <GLUT/glut.h>
29 #include <OpenGL/gl.h>
30 #include <OpenGL/glu.h>
31 #else
32 #include <GL/gl.h>
33 #include <GL/glu.h>
34 #include <GL/glut.h>
35 #ifdef HAVE_FREEGLUT_EXT_H
36 #include <GL/freeglut_ext.h>
37 #endif
38 #endif
39 #endif
40 
41 using namespace mrpt;
42 using namespace mrpt::gui;
43 using namespace mrpt::opengl;
44 using namespace mrpt::math;
45 using namespace mrpt::img;
46 using namespace std;
47 
48 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
49 
50 #if !wxUSE_GLCANVAS
51 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild wxWidgets"
52 #endif
53 
55 
56 namespace mrpt::gui
57 {
58 class CMyGLCanvas_DisplayWindow3D : public mrpt::gui::CWxGLCanvasBase
59 {
60  public:
61  CMyGLCanvas_DisplayWindow3D(
62  CDisplayWindow3D* win3D, wxWindow* parent, wxWindowID id = wxID_ANY,
63  const wxPoint& pos = wxDefaultPosition,
64  const wxSize& size = wxDefaultSize, long style = 0,
65  const wxString& name = _T("CMyGLCanvas_DisplayWindow3D"));
66 
67  ~CMyGLCanvas_DisplayWindow3D() override;
68 
69  CDisplayWindow3D* m_win3D = nullptr;
70 
71  void OnCharCustom(wxKeyEvent& event) override;
72  void OnMouseDown(wxMouseEvent& event);
73  void OnMouseMove(wxMouseEvent& event);
74 
75  void OnPreRender() override;
76  void OnPostRender() override;
77  void OnPostRenderSwapBuffers(double At, wxPaintDC& dc) override;
78 
79  static void display3D_processKeyEvent(
80  CDisplayWindow3D* m_win3D, wxKeyEvent& ev);
81 };
82 } // namespace mrpt::gui
83 
84 CMyGLCanvas_DisplayWindow3D::CMyGLCanvas_DisplayWindow3D(
85  CDisplayWindow3D* win3D, wxWindow* parent, wxWindowID id,
86  const wxPoint& pos, const wxSize& size, long style, const wxString& name)
87  : CWxGLCanvasBase(parent, id, pos, size, style, name), m_win3D(win3D)
88 {
89  this->Bind(wxEVT_CHAR, &CMyGLCanvas_DisplayWindow3D::OnCharCustom, this);
90  this->Bind(
91  wxEVT_CHAR_HOOK, &CMyGLCanvas_DisplayWindow3D::OnCharCustom, this);
92  this->Bind(
93  wxEVT_LEFT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown, this);
94  this->Bind(
95  wxEVT_RIGHT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown, this);
96  this->Bind(wxEVT_MOTION, &CMyGLCanvas_DisplayWindow3D::OnMouseMove, this);
97 }
98 
99 void CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(
100  CDisplayWindow3D* m_win3D, wxKeyEvent& ev)
101 {
102  if (m_win3D)
103  {
104  if (ev.AltDown() && ev.GetKeyCode() == MRPTK_RETURN)
105  {
107  m_win3D->m_lastFullScreen, mrpt::system::now()) > 0.2)
108  {
109  m_win3D->m_lastFullScreen = mrpt::system::now();
110  cout << "[CDisplayWindow3D] Switching fullscreen...\n";
111  auto* win = (C3DWindowDialog*)m_win3D->m_hwnd.get();
112  if (win)
113  {
114  win->ShowFullScreen(!win->IsFullScreen());
115  }
116  }
117  // Alt+Enter: Don't notify on this key stroke, since if we're
118  // switching to fullscreen
119  // and the user is waiting for a key to close the window, a runtime
120  // crash will occur,
121  // so return now:
122  return;
123  }
124 
125  const int code = ev.GetKeyCode();
127 
128  m_win3D->m_keyPushedCode = code;
129  m_win3D->m_keyPushedModifier = mod;
130  m_win3D->m_keyPushed = true;
131 
132  // Send the event:
133  try
134  {
135  m_win3D->publishEvent(mrptEventWindowChar(m_win3D, code, mod));
136  }
137  catch (...)
138  {
139  }
140  }
141  // ev.Skip(); // Pass the event to whoever else.
142 }
143 
144 void CMyGLCanvas_DisplayWindow3D::OnCharCustom(wxKeyEvent& ev)
145 {
146  CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
147 }
148 
149 void CMyGLCanvas_DisplayWindow3D::OnMouseDown(wxMouseEvent& event)
150 {
151  // Send the event:
152  if (m_win3D && m_win3D->hasSubscribers())
153  {
154  try
155  {
157  m_win3D, TPixelCoord(event.GetX(), event.GetY()),
158  event.LeftDown(), event.RightDown()));
159  }
160  catch (...)
161  {
162  }
163  }
164 
165  event.Skip(); // so it's processed by the wx system!
166 }
167 
168 void CMyGLCanvas_DisplayWindow3D::OnMouseMove(wxMouseEvent& event)
169 {
170  // Send the event:
171  if (m_win3D && m_win3D->hasSubscribers())
172  {
173  try
174  {
176  m_win3D, TPixelCoord(event.GetX(), event.GetY()),
177  event.LeftDown(), event.RightDown()));
178  }
179  catch (...)
180  {
181  }
182  }
183 
184  event.Skip(); // so it's processed by the wx system!
185 }
186 
187 CMyGLCanvas_DisplayWindow3D::~CMyGLCanvas_DisplayWindow3D()
188 {
189  // Ensure all OpenGL resources are freed before the opengl context is gone:
190  if (getOpenGLSceneRef()) getOpenGLSceneRef()->unloadShaders();
191 
192  // Unbind all objects, free all buffers:
193  auto& scene = getOpenGLSceneRef();
194  if (scene) scene->freeOpenGLResources();
195 }
196 
197 void CMyGLCanvas_DisplayWindow3D::OnPreRender()
198 {
199  auto& openGLSceneRef = getOpenGLSceneRef();
200  if (openGLSceneRef) openGLSceneRef.reset();
201 
202  COpenGLScene::Ptr& ptrScene = m_win3D->get3DSceneAndLock();
203  if (ptrScene) openGLSceneRef = ptrScene;
204 }
205 
206 void CMyGLCanvas_DisplayWindow3D::OnPostRender()
207 {
208  m_win3D->unlockAccess3DScene();
209 }
210 
211 void CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers(
212  double At, wxPaintDC& dc)
213 {
214  if (m_win3D) m_win3D->internal_setRenderingFPS(At > 0 ? 1.0 / At : 1e9);
215 
216  // If we are requested to do so, grab images to disk as they are rendered:
217  string grabFile;
218  if (m_win3D) grabFile = m_win3D->grabImageGetNextFile();
219  if (m_win3D && (!grabFile.empty() || m_win3D->isCapturingImgs()))
220  {
221  int w, h;
222  dc.GetSize(&w, &h);
223 
224  // Save image directly from OpenGL - It could also use 4 channels and
225  // save with GL_BGRA_EXT
226  auto frame = CImage::Create(w, h, mrpt::img::CH_RGB);
227 
228  glPixelStorei(GL_PACK_ALIGNMENT, 1);
229  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
230 
231  glReadBuffer(GL_FRONT);
232  glReadPixels(0, 0, w, h, GL_BGR_EXT, GL_UNSIGNED_BYTE, (*frame)(0, 0));
233  frame->flipVertical();
234 
235  if (!grabFile.empty())
236  {
237  frame->saveToFile(grabFile);
238  m_win3D->internal_emitGrabImageEvent(grabFile);
239  }
240 
241  if (m_win3D->isCapturingImgs())
242  {
243  {
244  std::lock_guard<std::mutex> lock(
245  m_win3D->m_last_captured_img_cs);
246  m_win3D->m_last_captured_img = frame;
247  frame.reset();
248  }
249  }
250  }
251 }
252 
253 #endif // Wx + OpenGL
254 
255 #if MRPT_HAS_WXWIDGETS
256 
257 BEGIN_EVENT_TABLE(C3DWindowDialog, wxFrame)
258 
259 END_EVENT_TABLE()
260 
261 const long C3DWindowDialog::ID_MENUITEM1 = wxNewId();
262 const long C3DWindowDialog::ID_MENUITEM2 = wxNewId();
263 
265  CDisplayWindow3D* win3D, WxSubsystem::CWXMainFrame* parent, wxWindowID id,
266  const std::string& caption, wxSize initialSize)
267  : m_win3D(win3D), m_mainFrame(parent)
268 {
269 #if MRPT_HAS_OPENGL_GLUT
270 
271  Create(
272  parent, id, caption.c_str(), wxDefaultPosition, initialSize,
273  wxDEFAULT_FRAME_STYLE, _T("id"));
274 
275  wxIcon FrameIcon;
276  FrameIcon.CopyFromBitmap(mrpt::gui::WxSubsystem::getMRPTDefaultIcon());
277  SetIcon(FrameIcon);
278 
279  // Create the wxCanvas object:
280  m_canvas = new CMyGLCanvas_DisplayWindow3D(
281  win3D, this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
282 
283  // Events:
284  this->Bind(wxEVT_CLOSE_WINDOW, &C3DWindowDialog::OnClose, this);
285  this->Bind(wxEVT_MENU, &C3DWindowDialog::OnMenuClose, this, ID_MENUITEM1);
286  this->Bind(wxEVT_MENU, &C3DWindowDialog::OnMenuAbout, this, ID_MENUITEM2);
287  this->Bind(wxEVT_CHAR, &C3DWindowDialog::OnChar, this);
288  this->Bind(wxEVT_SIZE, &C3DWindowDialog::OnResize, this);
289 
290  // Increment number of windows:
291  // int winCount =
293 // cout << "[C3DWindowDialog] Notifying new window: " << winCount << endl;
294 #else
295  THROW_EXCEPTION("MRPT was compiled without OpenGL support");
296 #endif
297  // this->Iconize(false);
298 }
299 
300 // Destructor
302 {
303  // cout << "[C3DWindowDialog::~C3DWindowDialog]" << endl;
304 }
305 
306 // OnClose event:
307 void C3DWindowDialog::OnClose(wxCloseEvent& event)
308 {
309  // Send the event:
310  bool allow_close = true;
311  try
312  {
313  mrptEventWindowClosed ev(m_win3D, true /* allow close */);
314  m_win3D->publishEvent(ev);
315  allow_close = ev.allow_close;
316  }
317  catch (...)
318  {
319  }
320  if (!allow_close) return; // Don't process this close event.
321 
322  // cout << "[C3DWindowDialog::OnClose]" << endl;
323  // Set the m_hwnd=nullptr in our parent object.
325 
326  // Decrement number of windows:
328 
329  // Signal we are destroyed:
330  m_win3D->m_windowDestroyed.set_value();
331 
332  event.Skip(); // keep processing by parent classes.
333 }
334 
335 // Menu: Close
336 void C3DWindowDialog::OnMenuClose(wxCommandEvent& event) { Close(); }
337 // Menu: About
338 void C3DWindowDialog::OnMenuAbout(wxCommandEvent& event)
339 {
340  ::wxMessageBox(
341  _("3D Scene viewer\n Class gui::CDisplayWindow3D\n MRPT C++ library"),
342  _("About..."));
343 }
344 
345 void C3DWindowDialog::OnChar(wxKeyEvent& ev)
346 {
347 #if MRPT_HAS_OPENGL_GLUT
348  CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
349 #endif
350 }
351 
352 void C3DWindowDialog::OnResize(wxSizeEvent& event)
353 {
354 #if MRPT_HAS_OPENGL_GLUT
355  // Send the event:
356  if (m_win3D)
357  {
358  try
359  {
361  m_win3D, event.GetSize().GetWidth(),
362  event.GetSize().GetHeight()));
363  }
364  catch (...)
365  {
366  }
367  }
368  event.Skip(); // so it's processed by the wx system!
369 #endif
370 }
371 
372 #endif // MRPT_HAS_WXWIDGETS
373 
374 /*---------------------------------------------------------------
375  Constructor
376  ---------------------------------------------------------------*/
378  const std::string& windowCaption, unsigned int initialWindowWidth,
379  unsigned int initialWindowHeight)
380  : CBaseGUIWindow(static_cast<void*>(this), 300, 399, windowCaption),
381  m_lastFullScreen(mrpt::system::now())
382 {
383  m_3Dscene = COpenGLScene::Create();
384  CBaseGUIWindow::createWxWindow(initialWindowWidth, initialWindowHeight);
385 }
386 
388  const std::string& windowCaption, unsigned int initialWindowWidth,
389  unsigned int initialWindowHeight)
390 {
391  return std::make_shared<CDisplayWindow3D>(
392  windowCaption, initialWindowWidth, initialWindowHeight);
393 }
394 /*---------------------------------------------------------------
395  Destructor
396  ---------------------------------------------------------------*/
398 {
399  // get lock so we make sure nobody else is touching the window right now.
400  bool lock_ok = m_csAccess3DScene.try_lock_for(std::chrono::seconds(2));
401  m_csAccess3DScene.unlock();
402 
404 
405  if (!lock_ok)
406  std::cerr
407  << "[~CDisplayWindow3D] Warning: Timeout acquiring mutex lock.\n";
408 }
409 
410 /*---------------------------------------------------------------
411  resize
412  ---------------------------------------------------------------*/
413 void CDisplayWindow3D::resize(unsigned int width, unsigned int height)
414 {
415 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
416  if (!isOpen())
417  {
418  cerr << "[CDisplayWindow3D::setPos] Window closed!: " << m_caption
419  << endl;
420  return;
421  }
422 
423  // Send a request to destroy this object:
424  auto* REQ = new WxSubsystem::TRequestToWxMainThread[1];
425  REQ->source3D = this;
426  REQ->OPCODE = 303;
427  REQ->x = width;
428  REQ->y = height;
430 #else
431  MRPT_UNUSED_PARAM(width);
432  MRPT_UNUSED_PARAM(height);
433 #endif
434 }
435 
436 /*---------------------------------------------------------------
437  setPos
438  ---------------------------------------------------------------*/
439 void CDisplayWindow3D::setPos(int x, int y)
440 {
441 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
442  if (!isOpen())
443  {
444  cerr << "[CDisplayWindow3D::setPos] Window closed!: " << m_caption
445  << endl;
446  return;
447  }
448 
449  // Send a request to destroy this object:
450  auto* REQ = new WxSubsystem::TRequestToWxMainThread[1];
451  REQ->source3D = this;
452  REQ->OPCODE = 302;
453  REQ->x = x;
454  REQ->y = y;
456 #else
459 #endif
460 }
461 
462 /*---------------------------------------------------------------
463  setWindowTitle
464  ---------------------------------------------------------------*/
465 void CDisplayWindow3D::setWindowTitle(const std::string& str)
466 {
467 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
468  if (!isOpen())
469  {
470  cerr << "[CDisplayWindow3D::setWindowTitle] Window closed!: "
471  << m_caption << endl;
472  return;
473  }
474 
475  // Send a request to destroy this object:
476  auto* REQ = new WxSubsystem::TRequestToWxMainThread[1];
477  REQ->source3D = this;
478  REQ->OPCODE = 304;
479  REQ->str = str;
481 #else
482  MRPT_UNUSED_PARAM(str);
483 #endif
484 }
485 
487 {
488  m_csAccess3DScene.lock();
489  return m_3Dscene;
490 }
491 
493 
495 {
496 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
497  auto* win = (C3DWindowDialog*)m_hwnd.get();
498  if (win)
499  {
500  // win->Refresh(false); // Do not erase background
501  // We must do this from the wx thread!
502 
503  // Send refresh request:
504  auto* REQ = new WxSubsystem::TRequestToWxMainThread[1];
505  REQ->source3D = this;
506  REQ->OPCODE = 350;
508  }
509 #endif
510 }
511 
512 /*---------------------------------------------------------------
513  setCameraElevationDeg
514  ---------------------------------------------------------------*/
516 {
517 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
518  auto* win = (C3DWindowDialog*)m_hwnd.get();
519  if (win) win->m_canvas->setElevationDegrees(deg);
520 #else
521  MRPT_UNUSED_PARAM(deg);
522 #endif
523 }
524 
526 {
527 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
528  auto* win = (C3DWindowDialog*)m_hwnd.get();
529  if (win) win->m_canvas->setUseCameraFromScene(useIt);
530 #else
531  MRPT_UNUSED_PARAM(useIt);
532 #endif
533 }
534 
535 /*---------------------------------------------------------------
536  setCameraAzimuthDeg
537  ---------------------------------------------------------------*/
539 {
540 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
541  auto* win = (C3DWindowDialog*)m_hwnd.get();
542  if (win) win->m_canvas->setAzimuthDegrees(deg);
543 #else
544  MRPT_UNUSED_PARAM(deg);
545 #endif
546 }
547 
548 /*---------------------------------------------------------------
549  setCameraPointingToPoint
550  ---------------------------------------------------------------*/
551 void CDisplayWindow3D::setCameraPointingToPoint(float x, float y, float z)
552 {
553 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
554  auto* win = (C3DWindowDialog*)m_hwnd.get();
555  if (win)
556  {
557  win->m_canvas->setCameraPointing(x, y, z);
558  }
559 #else
563 #endif
564 }
565 
566 /*---------------------------------------------------------------
567  setCameraZoom
568  ---------------------------------------------------------------*/
570 {
571 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
572  auto* win = (C3DWindowDialog*)m_hwnd.get();
573  if (win) win->m_canvas->setZoomDistance(zoom);
574 #else
575  MRPT_UNUSED_PARAM(zoom);
576 #endif
577 }
578 
579 /*---------------------------------------------------------------
580  setCameraProjective
581  ---------------------------------------------------------------*/
583 {
584 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
585  auto* win = (C3DWindowDialog*)m_hwnd.get();
586  if (win) win->m_canvas->setCameraProjective(isProjective);
587 #else
588  MRPT_UNUSED_PARAM(isProjective);
589 #endif
590 }
591 
592 void CDisplayWindow3D::setMinRange(float new_min)
593 {
594  if (m_3Dscene)
595  {
597  m_3Dscene->getViewport("main");
598  if (gl_view)
599  {
600  float m, M;
601  gl_view->getViewportClipDistances(m, M);
602  gl_view->setViewportClipDistances(new_min, M);
603  }
604  }
605 }
606 void CDisplayWindow3D::setMaxRange(float new_max)
607 {
608  if (m_3Dscene)
609  {
611  m_3Dscene->getViewport("main");
612  if (gl_view)
613  {
614  float m, M;
615  gl_view->getViewportClipDistances(m, M);
616  gl_view->setViewportClipDistances(m, new_max);
617  }
618  }
619 }
620 
622 {
623 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
624  auto* win = (C3DWindowDialog*)m_hwnd.get();
625  if (win) return win->m_canvas->cameraFOV();
626 #endif
627  return .0f;
628 }
629 
631 {
632 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
633  auto* win = (C3DWindowDialog*)m_hwnd.get();
634  if (win) win->m_canvas->setCameraFOV(v);
635 #endif
636 }
637 
638 /*---------------------------------------------------------------
639  getCameraElevationDeg
640  ---------------------------------------------------------------*/
642 {
643 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
644  const auto* win = (const C3DWindowDialog*)m_hwnd.get();
645  return win ? win->m_canvas->getElevationDegrees() : 0;
646 #else
647  return 0;
648 #endif
649 }
650 
651 /*---------------------------------------------------------------
652  getCameraAzimuthDeg
653  ---------------------------------------------------------------*/
655 {
656 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
657  const auto* win = (const C3DWindowDialog*)m_hwnd.get();
658  return win ? win->m_canvas->getAzimuthDegrees() : 0;
659 #else
660  return 0;
661 #endif
662 }
663 
664 /*---------------------------------------------------------------
665  getCameraPointingToPoint
666  ---------------------------------------------------------------*/
668  float& x, float& y, float& z) const
669 {
670 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
671  const auto* win = (const C3DWindowDialog*)m_hwnd.get();
672  if (win)
673  {
674  x = win->m_canvas->getCameraPointingX();
675  y = win->m_canvas->getCameraPointingY();
676  z = win->m_canvas->getCameraPointingZ();
677  }
678  else
679  x = y = z = 0;
680 #else
684 #endif
685 }
686 
687 /*---------------------------------------------------------------
688  getCameraZoom
689  ---------------------------------------------------------------*/
691 {
692 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
693  const auto* win = (const C3DWindowDialog*)m_hwnd.get();
694  return win ? win->m_canvas->getZoomDistance() : 0;
695 #else
696  return 0;
697 #endif
698 }
699 
700 /*---------------------------------------------------------------
701  isCameraProjective
702  ---------------------------------------------------------------*/
704 {
705 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
706  const auto* win = (const C3DWindowDialog*)m_hwnd.get();
707  return win ? win->m_canvas->isCameraProjective() : true;
708 #else
709  return true;
710 #endif
711 }
712 
713 /*---------------------------------------------------------------
714  getLastMousePosition
715  ---------------------------------------------------------------*/
716 bool CDisplayWindow3D::getLastMousePosition(int& x, int& y) const
717 {
718 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
719  const auto* win = (const C3DWindowDialog*)m_hwnd.get();
720  if (!win) return false;
721  win->m_canvas->getLastMousePosition(x, y);
722  return true;
723 #else
726  return false;
727 #endif
728 }
729 
730 /*---------------------------------------------------------------
731  getLastMousePositionRay
732  ---------------------------------------------------------------*/
734 {
735  int x, y;
736  if (getLastMousePosition(x, y))
737  {
738  std::lock_guard<std::recursive_timed_mutex> lck(m_csAccess3DScene);
739  m_3Dscene->getViewport("main")->get3DRayForPixelCoord(x, y, ray);
740  return true;
741  }
742  else
743  return false;
744 }
745 
746 /*---------------------------------------------------------------
747  setCursorCross
748  ---------------------------------------------------------------*/
749 void CDisplayWindow3D::setCursorCross(bool cursorIsCross)
750 {
751 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
752  const auto* win = (const C3DWindowDialog*)m_hwnd.get();
753  if (!win) return;
754  win->m_canvas->SetCursor(
755  *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
756 #else
757  MRPT_UNUSED_PARAM(cursorIsCross);
758 #endif
759 }
760 
761 /*---------------------------------------------------------------
762  grabImagesStart
763  ---------------------------------------------------------------*/
764 void CDisplayWindow3D::grabImagesStart(const std::string& grab_imgs_prefix)
765 {
766  m_grab_imgs_prefix = grab_imgs_prefix;
767  m_grab_imgs_idx = 0;
768 }
769 
770 /*---------------------------------------------------------------
771  grabImagesStop
772  ---------------------------------------------------------------*/
774 /*---------------------------------------------------------------
775  grabImageGetNextFile
776  ---------------------------------------------------------------*/
778 {
779  if (m_grab_imgs_prefix.empty())
780  return string();
781  else
782  return format(
783  "%s%06u.png", m_grab_imgs_prefix.c_str(), m_grab_imgs_idx++);
784 }
785 
786 /*---------------------------------------------------------------
787  captureImagesStart
788  ---------------------------------------------------------------*/
790 /*---------------------------------------------------------------
791  captureImagesStop
792  ---------------------------------------------------------------*/
794 /*---------------------------------------------------------------
795  getLastWindowImage
796  ---------------------------------------------------------------*/
798 {
799  bool ret;
800 
801  {
802  std::lock_guard<std::mutex> lock(m_last_captured_img_cs);
804  {
805  out_img = *m_last_captured_img; // Copy the full image
806  ret = true;
807  }
808  else
809  ret = false;
810  }
811  return ret;
812 }
813 
814 /*---------------------------------------------------------------
815  getLastWindowImagePtr
816  ---------------------------------------------------------------*/
818 {
819  std::lock_guard<std::mutex> lock(m_last_captured_img_cs);
820  return m_last_captured_img;
821 }
822 
824 {
825  const double ALPHA = 0.99;
826  m_last_FPS = ALPHA * m_last_FPS + (1 - ALPHA) * FPS;
827 }
828 
829 // Called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
831 {
832  const mrptEvent3DWindowGrabImageFile ev(this, fil);
833  publishEvent(ev);
834 }
835 
836 // Returns the "main" viewport of the scene.
838 {
839  std::lock_guard<std::recursive_timed_mutex> lck(m_csAccess3DScene);
840  return m_3Dscene->getViewport("main");
841 }
842 
844 {
845  std::lock_guard<std::recursive_timed_mutex> lck(m_csAccess3DScene);
846  m_3Dscene->getViewport("main")->setImageView(img);
847 }
848 
850 {
851  std::lock_guard<std::recursive_timed_mutex> lck(m_csAccess3DScene);
852  m_3Dscene->getViewport("main")->setImageView(std::move(img));
853 }
854 
857  : m_win(win)
858 {
859  out_scene_ptr = m_win.get3DSceneAndLock();
860 }
862  : m_win(win)
863 {
865 }
867 {
869 }
An event sent by a window upon resize.
bool getLastMousePosition(int &x, int &y) const override
Gets the last x,y pixel coordinates of the mouse.
float getCameraAzimuthDeg() const
Get camera parameters programmatically.
bool getLastMousePositionRay(mrpt::math::TLine3D &ray) const
Gets the 3D ray for the direction line of the pixel where the mouse cursor is at. ...
static void pushPendingWxRequest(TRequestToWxMainThread *data)
Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "ne...
An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CD...
void OnMenuAbout(wxCommandEvent &event)
void unlockAccess3DScene()
Unlocks the access to the internal 3D scene.
An event sent by a window upon a mouse click, giving the (x,y) pixel coordinates. ...
std::atomic_int m_keyPushedCode
void OnClose(wxCloseEvent &event)
mrpt::gui::CDisplayWindow3D * source3D
Only one of source* can be non-nullptr, indicating the class that generated the request.
Definition: WxSubsystem.h:199
mrpt::img::CImage::Ptr getLastWindowImagePtr() const
Retrieve the last captured image from the window, as a smart pointer.
The data structure for each inter-thread request:
Definition: WxSubsystem.h:189
CDisplayWindow3DLocker(CDisplayWindow3D &win, mrpt::opengl::COpenGLScene::Ptr &out_scene_ptr)
Acquires the lock of the 3D scene of the referenced window, and returns a copy of the smart pointer t...
void setWindowTitle(const std::string &str) override
Changes the window title.
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
mrpt::void_ptr_noncopy m_hwnd
The window handle.
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
std::string m_caption
The caption of the window.
size_t size(const MATRIXLIKE &m, const int dim)
mrpt::opengl::COpenGLScene::Ptr & get3DSceneAndLock()
Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introductio...
void grabImagesStart(const std::string &grab_imgs_prefix=std::string("video_"))
Start to save rendered images to disk.
static int notifyWindowCreation()
Atomically increments the number of windows created with the main frame as parent.
void resize(unsigned int width, unsigned int height) override
Resizes the window, stretching the image to fit into the display area.
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically.
mrptKeyModifier
Definition: keycodes.h:156
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:86
void OnMenuClose(wxCommandEvent &event)
static wxBitmap getMRPTDefaultIcon()
void setMaxRange(float new_max)
Changes the camera max clip range (z) (used for gluPerspective.
STL namespace.
CDisplayWindow3D * m_win3D
Definition: WxSubsystem.h:393
static CDisplayWindow3D::Ptr Create(const std::string &windowCaption, unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Class factory returning a smart pointer.
void internal_emitGrabImageEvent(const std::string &fil)
called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
void setCameraProjective(bool isProjective)
Sets the camera as projective, or orthogonal.
float getCameraZoom() const
Get camera parameters programmatically.
void OnResize(wxSizeEvent &event)
An event sent by a window upon when it&#39;s about to be closed, either manually by the user or programma...
An event sent by a window when the mouse is moved over it.
void OnChar(wxKeyEvent &event)
void notifyChildWindowDestruction()
Called by wx main thread to set m_hwnd to NULL.
mrpt::opengl::COpenGLViewport::Ptr getDefaultViewport()
A short cut for getting the "main" viewport of the scene object, it is equivalent to: ...
void setMinRange(float new_min)
Changes the camera min clip range (z) (used for gluPerspective).
const long ID_MENUITEM1
This base provides a set of functions for maths stuff.
void getCameraPointingToPoint(float &x, float &y, float &z) const
Get camera parameters programmatically.
void setPos(int x, int y) override
Changes the position of the window on the screen.
~CDisplayWindow3D() override
Destructor.
std::string grabImageGetNextFile()
Increments by one the image counter and return the next image file name (Users normally don&#39;t want to...
bool isOpen()
Returns false if the user has already closed the window.
std::atomic< mrptKeyModifier > m_keyPushedModifier
A pair (x,y) of pixel coordinates (integer resolution).
Definition: TPixelCoord.h:40
An event sent by a window upon a char pressed by the user.
const long ID_MENUITEM2
mrpt::gui::CDisplayWindow3D::Ptr win
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
Definition: WxUtils.cpp:939
void forceRepaint()
Repaints the window.
void setImageView(const mrpt::img::CImage &img)
Set the "main" viewport into "image view"-mode, where an image is efficiently drawn (fitting the view...
float getFOV() const
Return the camera field of view (in degrees) (used for gluPerspective)
std::recursive_timed_mutex m_csAccess3DScene
Critical section for accesing m_3Dscene.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
mrpt::system::TTimeStamp m_lastFullScreen
This class implements the GUI thread required for the wxWidgets-based GUI.
Definition: WxSubsystem.h:96
void grabImagesStop()
Stops image grabbing started by grabImagesStart.
std::atomic_bool m_keyPushed
bool isCameraProjective() const
Sets the camera as projective, or orthogonal.
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
Definition: CObservable.h:53
void publishEvent(const mrptEvent &e) const
Called when you want this object to emit an event to all the observers currently subscribed to this o...
Definition: CObservable.cpp:57
void setCameraZoom(float zoom)
Changes the camera parameters programmatically.
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:13
void setCursorCross(bool cursorIsCross) override
Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) ...
void destroyWxWindow()
Must be called by child classes in their destructors.
bool getLastWindowImage(mrpt::img::CImage &out_img) const
Retrieve the last captured image from the window.
mrpt::img::CImage::Ptr m_last_captured_img
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
void createWxWindow(unsigned int initialWidth, unsigned int initialHeight)
Must be called by child classes just within the constructor.
void captureImagesStop()
Stop image grabbing.
CDisplayWindow3D(const std::string &windowCaption=std::string(), unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Constructor.
double timeDifference(const mrpt::system::TTimeStamp t_first, const mrpt::system::TTimeStamp t_later)
Returns the time difference from t1 to t2 (positive if t2 is posterior to t1), in seconds...
Definition: datetime.h:123
void internal_setRenderingFPS(double FPS)
Set the rendering FPS (users don&#39;t call this, the method is for internal MRPT objects only) ...
std::promise< void > m_windowDestroyed
This semaphore will be signaled when the wx window is destroyed.
mrpt::opengl::COpenGLScene::Ptr m_3Dscene
Internal OpenGL object (see general discussion in about usage of this object)
The base class for GUI window classes based on wxWidgets.
void setFOV(float v)
Changes the camera field of view (in degrees) (used for gluPerspective).
static int notifyWindowDestruction()
Atomically decrements the number of windows created with the main frame as parent.
void setCameraAzimuthDeg(float deg)
Changes the camera parameters programmatically.
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:148
void setCameraElevationDeg(float deg)
Changes the camera parameters programmatically.
void useCameraFromScene(bool useIt=true)
If set to true (default = false), the mouse-based scene navigation will be disabled and the camera po...
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
void captureImagesStart()
Enables the grabbing of CImage objects from screenshots of the window.
3D line, represented by a base point and a director vector.
Definition: TLine3D.h:19
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
float getCameraElevationDeg() const
Get camera parameters programmatically.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 3a26b90fd Wed Mar 25 20:17:03 2020 +0100 at miƩ mar 25 23:05:41 CET 2020