MRPT  1.9.9
CDisplayWindow3D.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef CDisplayWindow3D_H
10 #define CDisplayWindow3D_H
11 
15 #include <mrpt/img/CImage.h>
16 #include <mrpt/system/datetime.h>
17 
18 #include <mutex>
19 
20 namespace mrpt::gui
21 {
22 class C3DWindowDialog;
23 class CMyGLCanvas_DisplayWindow3D;
24 
25 /** A graphical user interface (GUI) for efficiently rendering 3D scenes in
26  * real-time.
27  * This class always contains internally an instance of opengl::COpenGLScene,
28  * which
29  * the objects, viewports, etc. to be rendered.
30  *
31  * Images can be grabbed automatically to disk for easy creation of videos.
32  * See CDisplayWindow3D::grabImagesStart (and for creating videos,
33  * mrpt::vision::CVideoFileWriter).
34  *
35  * A short-cut for displaying 2D images (using the OpenGL rendering hardware)
36  * is available
37  * through \a setImageView() and \a setImageView_fast(). Internally, these
38  * methods call methods
39  * in the "main" viewport of the window (see \a COpenGLViewport).
40  *
41  * Since the 3D rendering is performed in a detached thread, especial care
42  * must be taken
43  * when updating the 3D scene to be rendered. The process involves an
44  * internal critical section
45  * and it must always consist of these steps:
46  *
47  * \code
48  * mrpt::gui::CDisplayWindow3D win("My window");
49  *
50  * // Adquire the scene:
51  * mrpt::opengl::COpenGLScene::Ptr &ptrScene = win.get3DSceneAndLock();
52  *
53  * // Modify the scene:
54  * ptrScene->...
55  * // or replace by another scene:
56  * ptrScene = otherScene;
57  *
58  * // Unlock it, so the window can use it for redraw:
59  * win.unlockAccess3DScene();
60  *
61  * // Update window, if required
62  * win.forceRepaint();
63  * \endcode
64  *
65  * An alternative way of updating the scene is by creating, before locking the
66  * 3D window, a new object
67  * of class COpenGLScene, then locking the window only for replacing the smart
68  * pointer. This may be
69  * advantageous is generating the 3D scene takes a long time, since while the
70  * window
71  * is locked it will not be responsive to the user input or window redraw.
72  *
73  * It is safer against exceptions to use the auxiliary class
74  * CDisplayWindow3DLocker.
75  * \code
76  * mrpt::gui::CDisplayWindow3D win("My window");
77  * // ...
78  * { // The scene is adquired in this scope
79  * mrpt::opengl::COpenGLScene::Ptr ptrScene;
80  * mrpt::gui::CDisplayWindow3DLocker locker(win,ptrScene);
81  * //...
82  *
83  * } // scene is unlocked upon dtor of `locker`
84  * \endcode
85  *
86  * Notice however that a copy of the smart pointer is made, so replacement of
87  * the entire scene
88  * via `operator =` is not possible if using this method. Still, in general it
89  * should be preferred because
90  * the mutexes are automatically released in case of unexpected exceptions.
91  *
92  * The window can also display a set of 2D text messages overlapped to the 3D
93  * scene.
94  * See CDisplayWindow3D::addTextMessage
95  *
96  * For a list of supported events with the observer/observable pattern, see
97  * the discussion in mrpt::gui::CBaseGUIWindow.
98  * In addition to those events, this class introduces
99  * mrpt::gui::mrptEvent3DWindowGrabImageFile
100  *
101  * ** CDisplayWindow3D mouse view navigation cheatsheet **
102  * - <b>Orbit camera</b>: Left-button pressed + move
103  * - <b>Zoom in / out</b>:
104  * - Mouse scroll wheel, or
105  * - SHIFT+Left-button pressed + move up/down
106  * - <b>Look around (pivot camera)</b>: CTRL+Left-button pressed + move
107  * up/down
108  * - <b>Pan (XY plane)</b>: Right-button pressed + move
109  * - <b>Move camera along Z axis</b>: SHIFT+Left-button pressed + move
110  * left/right
111  *
112  * \sa The example /samples/display3D, the <a
113  * href="http://www.mrpt.org/Tutorial_3D_Scenes" > tutorial only</a>.
114  * \ingroup mrpt_gui_grp
115  */
117 {
118  public:
119  using Ptr = std::shared_ptr<CDisplayWindow3D>;
120  using ConstPtr = std::shared_ptr<const CDisplayWindow3D>;
121 
122  protected:
123  friend class C3DWindowDialog;
125 
126  /** Internal OpenGL object (see general discussion in about usage of this
127  * object) */
129  /** Critical section for accesing m_3Dscene */
130  mutable std::recursive_mutex m_csAccess3DScene;
131 
132  /** Throws an exception on initialization error */
134 
137 
139  unsigned int m_grab_imgs_idx;
140 
143  mutable std::mutex m_last_captured_img_cs;
144 
145  void doRender();
146 
148 
149  /** \sa getRenderingFPS */
150  double m_last_FPS;
151 
153 
154  public:
155  /** Constructor */
157  const std::string& windowCaption = std::string(),
158  unsigned int initialWindowWidth = 400,
159  unsigned int initialWindowHeight = 300);
160 
161  /** Class factory returning a smart pointer */
163  const std::string& windowCaption, unsigned int initialWindowWidth = 400,
164  unsigned int initialWindowHeight = 300);
165 
166  /** Destructor */
167  virtual ~CDisplayWindow3D();
168 
169  /** Gets a reference to the smart shared pointer that holds the internal
170  * scene (carefuly read introduction in gui::CDisplayWindow3D before use!)
171  * This also locks the critical section for accesing the scene, thus the
172  * window will not be repainted until it is unlocked.
173  * \note It is safer to use mrpt::gui::CDisplayWindow3DLocker instead.*/
175 
176  /** Unlocks the access to the internal 3D scene. It is safer to use
177  * mrpt::gui::CDisplayWindow3DLocker instead.
178  * Typically user will want to call forceRepaint after updating the scene.
179  */
180  void unlockAccess3DScene();
181 
182  /** Repaints the window. forceRepaint, repaint and updateWindow are all
183  * aliases of the same method */
184  void forceRepaint();
185  /** Repaints the window. forceRepaint, repaint and updateWindow are all
186  * aliases of the same method */
187  void repaint() { forceRepaint(); }
188  /** Repaints the window. forceRepaint, repaint and updateWindow are all
189  * aliases of the same method */
191  /** Return the camera field of view (in degrees) (used for gluPerspective)
192  */
193  float getFOV() const;
194  /** Changes the camera min clip range (z) (used for gluPerspective). The
195  * window is not updated with this method, call "forceRepaint" to update the
196  * 3D view. */
197  void setMinRange(double new_min);
198  /** Changes the camera max clip range (z) (used for gluPerspective. The
199  * window is not updated with this method, call "forceRepaint" to update the
200  * 3D view. */
201  void setMaxRange(double new_max);
202  /** Changes the camera field of view (in degrees) (used for gluPerspective).
203  * The window is not updated with this method, call "forceRepaint" to update
204  * the 3D view. */
205  void setFOV(float v);
206  /** Resizes the window, stretching the image to fit into the display area.
207  */
208  void resize(unsigned int width, unsigned int height) override;
209  /** Changes the position of the window on the screen. */
210  void setPos(int x, int y) override;
211  /** Changes the window title. */
212  void setWindowTitle(const std::string& str) override;
213  /** Changes the camera parameters programmatically */
214  void setCameraElevationDeg(float deg);
215  /** Changes the camera parameters programmatically */
216  void setCameraAzimuthDeg(float deg);
217  /** Changes the camera parameters programmatically */
218  void setCameraPointingToPoint(float x, float y, float z);
219  /** Changes the camera parameters programmatically */
220  void setCameraZoom(float zoom);
221  /** Sets the camera as projective, or orthogonal. */
222  void setCameraProjective(bool isProjective);
223  /** Get camera parameters programmatically */
224  float getCameraElevationDeg() const;
225  /** Get camera parameters programmatically */
226  float getCameraAzimuthDeg() const;
227  /** Get camera parameters programmatically */
228  void getCameraPointingToPoint(float& x, float& y, float& z) const;
229  /** Get camera parameters programmatically */
230  float getCameraZoom() const;
231  /** Sets the camera as projective, or orthogonal */
232  bool isCameraProjective() const;
233  /** If set to true (default = false), the mouse-based scene navigation will
234  * be disabled and the camera position will be determined by the opengl
235  * viewports in the 3D scene */
236  void useCameraFromScene(bool useIt = true);
237  /** Gets the 3D ray for the direction line of the pixel where the mouse
238  * cursor is at. \return False if the window is closed. \sa
239  * getLastMousePosition */
241  /** Gets the last x,y pixel coordinates of the mouse. \return False if the
242  * window is closed. \sa getLastMousePositionRay */
243  virtual bool getLastMousePosition(int& x, int& y) const override;
244  /** Set cursor style to default (cursorIsCross=false) or to a cross
245  * (cursorIsCross=true) \sa getLastMousePositionRay */
246  virtual void setCursorCross(bool cursorIsCross) override;
247 
248  /** Start to save rendered images to disk.
249  * Images will be saved independently as png files, depending on
250  * the template path passed to this method. For example:
251  *
252  * path_prefix: "./video_"
253  *
254  * Will generate "./video_000001.png", etc.
255  *
256  * If this feature is enabled, the window will emit events of the type
257  * mrpt::gui::mrptEvent3DWindowGrabImageFile() which you can subscribe to.
258  *
259  * \sa grabImagesStop
260  */
261  void grabImagesStart(
262  const std::string& grab_imgs_prefix = std::string("video_"));
263 
264  /** Stops image grabbing started by grabImagesStart
265  * \sa grabImagesStart
266  */
267  void grabImagesStop();
268 
269  /** Enables the grabbing of CImage objects from screenshots of the window.
270  * \sa getLastWindowImage
271  */
272  void captureImagesStart();
273 
274  /** Stop image grabbing
275  * \sa captureImagesStart
276  */
277  void captureImagesStop();
278 
279  /** Retrieve the last captured image from the window.
280  * You MUST CALL FIRST captureImagesStart to enable image grabbing.
281  * \return false if there was no time yet for grabbing any image (then, the
282  * output image is undefined).
283  * \sa captureImagesStart, getLastWindowImagePtr
284  */
285  bool getLastWindowImage(mrpt::img::CImage& out_img) const;
286 
287  /** Retrieve the last captured image from the window, as a smart pointer.
288  * This method is more efficient than getLastWindowImage since only a copy
289  * of the pointer is performed, while
290  * getLastWindowImage would copy the entire image.
291  *
292  * You MUST CALL FIRST captureImagesStart to enable image grabbing.
293  * \Note If there was no time yet for grabbing any image, an empty smart
294  * pointer will be returned.
295  * \sa captureImagesStart, getLastWindowImage
296  */
298 
299  /** Increments by one the image counter and return the next image file name
300  * (Users normally don't want to call this method).
301  * \sa grabImagesStart
302  */
304 
305  bool isCapturingImgs() const { return m_is_capturing_imgs; }
306  /** Add 2D text messages overlapped to the 3D rendered scene. The string
307  * will remain displayed in the 3D window
308  * until it's changed with subsequent calls to this same method, or all
309  * the texts are cleared with clearTextMessages().
310  *
311  * \param x The X position, interpreted as absolute pixels from the left
312  * if X>=1, absolute pixels from the left if X<0 or as a width factor if in
313  * the range [0,1[.
314  * \param y The Y position, interpreted as absolute pixels from the bottom
315  * if Y>=1, absolute pixels from the top if Y<0 or as a height factor if in
316  * the range [0,1[.
317  * \param text The text string to display.
318  * \param color The text color. For example: TColorf(1.0,1.0,1.0)
319  * \param unique_index An "index" for this text message, so that
320  * subsequent calls with the same index will overwrite this text message
321  * instead of creating new ones.
322  *
323  * You'll need to refresh the display manually with forceRepaint().
324  *
325  * \sa clearTextMessages
326  */
327  void addTextMessage(
328  const double x, const double y, const std::string& text,
329  const mrpt::img::TColorf& color = mrpt::img::TColorf(1.0, 1.0, 1.0),
330  const size_t unique_index = 0,
331  const mrpt::opengl::TOpenGLFont font =
333 
334  /** overload with more font parameters - refer to
335  * mrpt::opengl::gl_utils::glDrawText()
336  * Available fonts are enumerated at mrpt::opengl::gl_utils::glSetFont() */
337  void addTextMessage(
338  const double x_frac, const double y_frac, const std::string& text,
339  const mrpt::img::TColorf& color, const std::string& font_name,
340  const double font_size,
342  const size_t unique_index = 0, const double font_spacing = 1.5,
343  const double font_kerning = 0.1, const bool draw_shadow = false,
344  const mrpt::img::TColorf& shadow_color = mrpt::img::TColorf(0, 0, 0));
345 
346  /** Clear all text messages created with addTextMessage().
347  * You'll need to refresh the display manually with forceRepaint().
348  * \sa addTextMessage
349  */
350  void clearTextMessages();
351 
352  /** Get the average Frames Per Second (FPS) value from the last 250
353  * rendering events */
354  double getRenderingFPS() const { return m_last_FPS; }
355  /** A short cut for getting the "main" viewport of the scene object, it is
356  * equivalent to:
357  * \code
358  * mrpt::opengl::COpenGLScene::Ptr &scene = win3D.get3DSceneAndLock();
359  * viewport = scene->getViewport("main");
360  * win3D.unlockAccess3DScene();
361  * \endcode
362  */
364 
365  /** Set the "main" viewport into "image view"-mode, where an image is
366  * efficiently drawn (fitting the viewport area) using an OpenGL textured
367  * quad.
368  * Call this method with the new image to update the displayed image (but
369  * recall to first lock the parent openglscene's critical section, then do
370  * the update, then release the lock, and then issue a window repaint).
371  * Internally, the texture is drawn using a mrpt::opengl::CTexturedPlane
372  * The viewport can be reverted to behave like a normal viewport by
373  * calling setNormalMode()
374  * \sa setImageView_fast, COpenGLViewport
375  * \note This method already locks/unlocks the 3D scene of the window, so
376  * the user must NOT call get3DSceneAndLock() / unlockAccess3DScene()
377  * before/after calling it.
378  */
379  void setImageView(const mrpt::img::CImage& img);
380 
381  /** Just like \a setImageView but moves the internal image memory instead of
382  * making a copy, so it's faster but empties the input image.
383  * \sa setImageView, COpenGLViewport
384  * \note This method already locks/unlocks the 3D scene of the window, so
385  * the user must NOT call get3DSceneAndLock() / unlockAccess3DScene()
386  * before/after calling it.
387  */
389 
390  protected:
391  /** Set the rendering FPS (users don't call this, the method is for internal
392  * MRPT objects only) \sa getRenderingFPS */
393  void internal_setRenderingFPS(double FPS);
394  /** called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers */
395  void internal_emitGrabImageEvent(const std::string& fil);
396 
397 }; // End of class def.
398 
399 /** @name Events specific to CDisplayWindow3D
400  @{ */
401 
402 /** An event sent by a CDisplayWindow3D window when an image is saved after
403  * enabling this feature with CDisplayWindow3D::grabImagesStart()
404  *
405  * IMPORTANTE NOTICE: Event handlers in your observer class will be invoked
406  * from the wxWidgets internal MRPT thread,
407  * so all your code in the handler must be thread safe.
408  */
410 {
411  protected:
412  /** Just to allow this class to be polymorphic */
413  virtual void do_nothing() override {}
414  public:
416  CDisplayWindow3D* obj, const std::string& _img_file)
417  : source_object(obj), img_file(_img_file)
418  {
419  }
420 
422  /** The absolute path of the file that has been just saved. */
424 }; // End of class def.
425 
426 /** @} */
427 
428 /** Auxiliary class for safely claiming the 3DScene of a
429  * mrpt::gui::CDisplayWindow3D.
430  * The mutex will be hold between ctor and dtor calls of objects of this class,
431  * safely releasing
432  * the lock upon exceptions. See example usage code in docs of
433  * mrpt::gui::CDisplayWindow3D
434  *
435  * \ingroup mrpt_gui_grp
436  * \note New in MRPT 1.5.0
437  */
439 {
440  public:
441  /** Acquires the lock of the 3D scene of the referenced window, and returns
442  * a copy of the smart pointer to it. */
445  /** Acquires the lock of the 3D scene of the referenced window. Use this
446  * signature when the scene object is not required. */
449 
450  private:
452 };
453 
454 }
455 #endif
456 
457 
The base class for GUI window classes.
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
static CDisplayWindow3D::Ptr Create(const std::string &windowCaption, unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Class factory returning a smart pointer.
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically.
void updateWindow()
Repaints the window.
mrpt::img::CImage::Ptr getLastWindowImagePtr() const
Retrieve the last captured image from the window, as a smart pointer.
void internal_setRenderingFPS(double FPS)
Set the rendering FPS (users don't call this, the method is for internal MRPT objects only)
std::shared_ptr< const CDisplayWindow3D > ConstPtr
void forceRepaint()
Repaints the window.
void unlockAccess3DScene()
Unlocks the access to the internal 3D scene.
void setPos(int x, int y) override
Changes the position of the window on the screen.
friend class CMyGLCanvas_DisplayWindow3D
virtual void setCursorCross(bool cursorIsCross) override
Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true)
std::recursive_mutex m_csAccess3DScene
Critical section for accesing m_3Dscene.
bool getLastMousePositionRay(mrpt::math::TLine3D &ray) const
Gets the 3D ray for the direction line of the pixel where the mouse cursor is at.
void setCameraZoom(float zoom)
Changes the camera parameters programmatically.
float getCameraElevationDeg() const
Get camera parameters programmatically.
void setImageView_fast(mrpt::img::CImage &img)
Just like setImageView but moves the internal image memory instead of making a copy,...
void getCameraPointingToPoint(float &x, float &y, float &z) const
Get camera parameters programmatically.
void setFOV(float v)
Changes the camera field of view (in degrees) (used for gluPerspective).
void setWindowTitle(const std::string &str) override
Changes the window title.
void setCameraProjective(bool isProjective)
Sets the camera as projective, or orthogonal.
void grabImagesStart(const std::string &grab_imgs_prefix=std::string("video_"))
Start to save rendered images to disk.
CDisplayWindow3D(const std::string &windowCaption=std::string(), unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Constructor.
mrpt::opengl::COpenGLScene::Ptr & get3DSceneAndLock()
Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introductio...
void setCameraAzimuthDeg(float deg)
Changes the camera parameters programmatically.
virtual bool getLastMousePosition(int &x, int &y) const override
Gets the last x,y pixel coordinates of the mouse.
virtual ~CDisplayWindow3D()
Destructor.
bool isCameraProjective() const
Sets the camera as projective, or orthogonal.
void captureImagesStart()
Enables the grabbing of CImage objects from screenshots of the window.
void setMaxRange(double new_max)
Changes the camera max clip range (z) (used for gluPerspective.
void resize(unsigned int width, unsigned int height) override
Resizes the window, stretching the image to fit into the display area.
float getFOV() const
Return the camera field of view (in degrees) (used for gluPerspective)
void internal_emitGrabImageEvent(const std::string &fil)
called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
void createOpenGLContext()
Throws an exception on initialization error.
mrpt::opengl::COpenGLViewport::Ptr getDefaultViewport()
A short cut for getting the "main" viewport of the scene object, it is equivalent to:
double getRenderingFPS() const
Get the average Frames Per Second (FPS) value from the last 250 rendering events.
mrpt::void_ptr_noncopy m_DisplayDeviceContext
mrpt::opengl::COpenGLScene::Ptr m_3Dscene
Internal OpenGL object (see general discussion in about usage of this object)
mrpt::system::TTimeStamp m_lastFullScreen
std::string grabImageGetNextFile()
Increments by one the image counter and return the next image file name (Users normally don't want to...
float getCameraAzimuthDeg() const
Get camera parameters programmatically.
mrpt::img::CImage::Ptr m_last_captured_img
void repaint()
Repaints the window.
void setMinRange(double new_min)
Changes the camera min clip range (z) (used for gluPerspective).
float getCameraZoom() const
Get camera parameters programmatically.
void clearTextMessages()
Clear all text messages created with addTextMessage().
void setImageView(const mrpt::img::CImage &img)
Set the "main" viewport into "image view"-mode, where an image is efficiently drawn (fitting the view...
void addTextMessage(const double x, const double y, const std::string &text, const mrpt::img::TColorf &color=mrpt::img::TColorf(1.0, 1.0, 1.0), const size_t unique_index=0, const mrpt::opengl::TOpenGLFont font=mrpt::opengl::MRPT_GLUT_BITMAP_TIMES_ROMAN_24)
Add 2D text messages overlapped to the 3D rendered scene.
mrpt::void_ptr_noncopy m_GLRenderingContext
void grabImagesStop()
Stops image grabbing started by grabImagesStart.
bool getLastWindowImage(mrpt::img::CImage &out_img) const
Retrieve the last captured image from the window.
void setCameraElevationDeg(float deg)
Changes the camera parameters programmatically.
void captureImagesStop()
Stop image grabbing.
std::shared_ptr< CDisplayWindow3D > Ptr
void useCameraFromScene(bool useIt=true)
If set to true (default = false), the mouse-based scene navigation will be disabled and the camera po...
Auxiliary class for safely claiming the 3DScene of a mrpt::gui::CDisplayWindow3D.
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...
An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CD...
const std::string & img_file
The absolute path of the file that has been just saved.
mrptEvent3DWindowGrabImageFile(CDisplayWindow3D *obj, const std::string &_img_file)
virtual void do_nothing() override
Just to allow this class to be polymorphic.
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:131
std::shared_ptr< CImage > Ptr
Definition: img/CImage.h:132
std::shared_ptr< COpenGLScene > Ptr
Definition: COpenGLScene.h:61
std::shared_ptr< COpenGLViewport > Ptr
The basic event type for the observer-observable pattern in MRPT.
Definition: mrptEvent.h:33
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
const GLdouble * v
Definition: glext.h:3678
GLuint color
Definition: glext.h:8300
GLenum GLint GLint y
Definition: glext.h:3538
GLenum GLsizei width
Definition: glext.h:3531
GLint GLvoid * img
Definition: glext.h:3763
GLenum GLint x
Definition: glext.h:3538
GLdouble GLdouble z
Definition: glext.h:3872
GLenum GLsizei GLsizei height
Definition: glext.h:3554
GLsizei const GLchar ** string
Definition: glext.h:4101
TOpenGLFont
Existing fonts for 2D texts in mrpt::opengl methods.
Definition: opengl_fonts.h:24
@ MRPT_GLUT_BITMAP_TIMES_ROMAN_24
Definition: opengl_fonts.h:27
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
Definition: datetime.h:40
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:15
TOpenGLFontStyle
Different style for vectorized font rendering.
Definition: opengl_fonts.h:35
@ NICE
renders glyphs filled with antialiased outlines
Definition: opengl_fonts.h:38
A RGB color - floats in the range [0,1].
Definition: TColor.h:78
3D line, represented by a base point and a director vector.
mrpt::gui::CDisplayWindow3D::Ptr win



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 814d80880 Fri Aug 24 01:51:28 2018 +0200 at mar 26 may 2026 12:30:59 CEST