GLViewer.h 28.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/*
 *	(c) LSIIT, UMR CNRS/UdS
 *	Authors: O. Gnevaux, F. Larue.
 *
 *	See licence.txt for additional information.
 */


#ifndef GLVIEWER_H
#define GLVIEWER_H


13
#include "GLViewerDefs.h"
14 15 16
#include "../GPU/GPU.h"
#include "DisplayableInterface.h"
#include <set>
17
#include <chrono>
18 19 20
#include "MetricGrid.h"
#include "PickedPoint.h"
#include "UIData.h"
21
#include "Frustum.h"
22 23 24 25 26 27
class InfoBarManager;
class Panel;




28
class GLVIEWER_API GLViewer : public QOpenGLWidget
29 30 31 32 33 34 35
{
    Q_OBJECT

    /******************\
    | Internal type(s) |
    \******************/
public:
36 37 38 39 40 41 42
    struct RenderState
    {
        DisplayDoF      DoF;

        QVector3D       focusPoint;
        float           fovY;
	    float           distToFocusPoint;
43 44
        float           nearPlaneFactor;
        float           farPlaneFactor;
45 46 47 48 49
        float           zNear;
        float           zFar;
        QMatrix4x4      viewRotationMatrix;
        QMatrix4x4      lightRotationMatrix;

50
        bool            isOrthographic;
51 52 53 54
        bool            isWireframeEnabled;
        bool            isLightingEnabled;
        bool            isLightTrackingEnabled;
        bool            isCullingEnabled;
55 56
        MetricGrid      metricGrid2D;
        MetricGrid      metricGrid3D;
57 58 59 60

        unsigned int    pointSize;
    };

61
    class GLVIEWER_API NavigationControl
62
    {
63
        GLViewer            *m_Viewer;
64 65 66 67 68 69 70 71 72 73 74 75 76 77

    public:
        inline NavigationControl( GLViewer *viewer ) : m_Viewer(viewer) {}
        inline GLViewer*    GetViewer() const  { return m_Viewer; }

        virtual void        mouseMoveEvent( double dx, double dy, QMouseEvent *evt );
        virtual void        wheelEvent( double delta, QWheelEvent* evt );
        virtual void        mouseDoubleClickEvent( QMouseEvent *evt );
        virtual bool        keyPressEvent( QKeyEvent *evt );

        virtual void        updateProjectionMatrix( QMatrix4x4 &m );
        virtual void        updateViewMatrix( QMatrix4x4 &m );
    };

78
protected:
79
    class DisplayableInfo;
80 81 82 83 84 85

    typedef std::map<QString,DisplayableFactoryInterface*> FactoryMap;
    typedef std::list<DisplayableInfo*> DisplayableList;
    typedef std::map<int,DisplayableList> PriorityMap;
    typedef std::map<const GenericUIData*,DisplayableInfo> DisplayableMap;

86 87 88
    using TimeMeasurement = std::chrono::high_resolution_clock::time_point;


89 90 91 92 93 94 95 96
    class DisplayableInfo
    {
        QMatrix4x4                  userTransform;
        QMatrix4x4                  packingTransform;
        QMatrix4x4                  fullTransform;

    public:
        void                        Initialize( DisplayableInterface *displayable,
97
                                                DisplayableList::iterator priorityPos,
98 99
                                                UIParamSet &params );

100
        inline void                 SetUserTransform( const QMatrix4x4& tr )    { userTransform = tr; fullTransform = tr * packingTransform; }
101
        inline const QMatrix4x4&    UserTransform() const                       { return userTransform; }
102 103 104 105
        inline void                 SetPackingTransform( const QMatrix4x4& tr ) { packingTransform = tr; fullTransform = userTransform * tr; }
        inline const QMatrix4x4&    GetTransform() const                        { return fullTransform; }

        DisplayableInterface        *displayable;
106 107
        QVector<SelectionManager*>  selectionMgr;
        SelectionManager*           currentSelectionMgr;
108 109 110 111
        DisplayableList::iterator   posInPriorityList;
        Box3f                       boundingBox;
    };

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    enum SelectionToolName
    {
        SELECTION_TOOL_DISK     = 0,
        SELECTION_TOOL_BOX      ,
        SELECTION_TOOL_LASSO    ,
        SELECTION_TOOL_END      ,
    };

    /*******************\
    | Class variable(s) |
    \*******************/
protected:
    static const int                PICKING_WIN_RADIUS = 5;
    static const char*              s_PickingVPG;
    static const char*              s_PickingFPG;

    static const char*              s_ZBufferVPG;
    static const char*              s_ZBufferFPG;

131 132 133
    static QString                  s_MetricGrid2DSuffix;
    static QString                  s_MetricGrid3DSuffix;

134 135 136 137 138 139
    static QImage                   s_Logos[4];
    bool                            m_IsDemoModeEnabled = false;
    QImage                          m_CurrentLogos[4];
    void                            updateDemoModeLogos();
    void                            displayDemoModeLogos();

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
public:
    static QVector3D                BgTopColor;
    static QVector3D                BgBottomColor;

    static QVector3D                CoolColor;
    static QVector3D                WarmColor;

    static QVector3D                LightColor;
    static QVector3D                AmbientColor;
    static QVector3D                SpecularColor;

    static float                    Ambient;
    static float                    Specular;
    static float                    Shininess;

155 156 157 158
    /********************\
    | Member variable(s) |
    \********************/
protected:
159
    RenderState                     m_View;
160
    QList<NavigationControl*>       m_NavigationCtrl;
161 162 163 164 165 166

    float                           m_SpeedFactor;
    float                           m_CtrlSpeedFactor;
    float                           m_ShiftSpeedFactor;

	QPoint		                    m_PrevMousePos;
167
	QPoint		                    m_ClickMousePos;
168 169 170 171 172 173 174 175 176 177 178

    FactoryMap                      m_Factories;
    DisplayableMap                  m_Displayables;
    PriorityMap                     m_DisplayablesByPriority;
    DisplayableList                 m_AddingOrder;
    QVBoxLayout                     *m_DisplayOptionsLayout;

    InfoBarManager                  *m_InfoBarManager;

    QList<DisplayableInterface*>    m_AnimationStartingQueue;
    QList<DisplayableInterface*>    m_AnimationStoppingQueue;
179 180
    TimeMeasurement                 m_AnimationFrameTime;
    QMap<DisplayableInterface*,double>   m_ActiveAnimations;
181
    bool                            m_AnimationsRunningAtPreviousFrame;
182 183 184
	float							m_AnimationFrameRate;

	bool							m_PerformanceCounterEnabled;
185 186 187 188 189 190 191 192 193

    bool                            m_SelectionEnabled;
    SelectionToolName               m_SelectionCurrentToolName;
    SelectionTool::Context          m_SelectionContext;
    SelectionTool*                  m_SelectionCurrentTool;
    std::vector<SelectionTool*>     m_SelectionTools;

    GPU::Shader                     m_PickingShader;
    GPU::Shader                     m_ZBufferShader;
194 195 196
    GPU::Texture2D                  m_SelectionDepthTexture;
    GPU::FrameBuffer                m_SelectionDepthBuffer;
    SelectionZBufferUpdateMode      m_SelectionZBufferUpdateMode;
197

198 199
    DisplayableInfo                 *m_BelowCursor;

200 201 202 203 204 205 206 207 208 209 210 211
    // View related transformations.

    bool                            m_MustUpdateFocal;
    double                          m_Focal;

    bool                            m_MustUpdateProjectionMatrix;
    QMatrix4x4                      m_ProjectionMatrix;
    QMatrix4x4                      m_ProjectionMatrixInverse;

    bool                            m_MustUpdateViewMatrix;
    QMatrix4x4                      m_ViewMatrix;
    QMatrix4x4                      m_ViewMatrixInverse;
212
    QMatrix4x4                      m_ViewRotationMatrixInverse;
213 214 215 216

    QMatrix4x4                      m_ViewProjectionMatrix;
    QMatrix4x4                      m_ViewProjectionMatrixInverse;

217 218
    Frustum                         m_Frustum;

219 220 221
    bool                            m_ChangeNearPlaneMode;
    bool                            m_ChangeFarPlaneMode;

222 223
    bool                            m_IsSelectionAllowed;

224 225
    bool                            m_IsCursorInside;

226 227 228 229 230 231 232 233 234
    bool                            m_IsGrabbingTranslationEnabled = false;
    bool                            m_IsGrabbingRotationEnabled = false;
    int                             m_GrabbingAxisConstraint = -1;
    void                            enterGrabbingMode( bool translation );
    void                            exitGrabbingMode( bool validateTransformations );
    inline void                     resetGrabbingMode()         { bool tr = m_IsGrabbingTranslationEnabled; exitGrabbingMode(false); enterGrabbingMode(tr); }
    void                            onGrabbing( QMouseEvent *evt );
    inline bool                     isGrabbingEnabled() const   { return m_IsGrabbingTranslationEnabled  ||  m_IsGrabbingRotationEnabled; }

235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
    /*****************************\
    | Constructor(s) / destructor |
    \*****************************/
public:
    GLViewer( DisplayDoF dof,
              QWidget *parent = NULL,
              Qt::WindowFlags f = 0 );
    GLViewer( DisplayDoF dof,
              const QSurfaceFormat &format,
              QWidget *parent = NULL,
              Qt::WindowFlags f = 0 );
    virtual ~GLViewer();

    /********************\
    | Member function(s) |
    \********************/
protected:
252 253
    void                                        initMetricGrids();

254
    virtual void                                enterEvent( QEvent *evt );
255
    virtual void                                leaveEvent( QEvent* evt );
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
    virtual void	                            mousePressEvent( QMouseEvent *evt );
    virtual void                                mouseReleaseEvent( QMouseEvent *evt );
	virtual void	                            mouseMoveEvent( QMouseEvent *evt );
    virtual void                                wheelEvent( QWheelEvent *evt );
    virtual void                                mouseDoubleClickEvent( QMouseEvent *evt );
    virtual void                                keyPressEvent( QKeyEvent *evt );
    virtual void                                keyReleaseEvent( QKeyEvent *evt );
    virtual bool                                event( QEvent *evt );

    void                                        setupScene();
    virtual void                                releaseScene()                                  {}

    void                                        updateSelectionMode( const Qt::KeyboardModifiers &modifiers );

    DisplayableMap::iterator                    removeDisplayable_Internal( DisplayableMap::iterator &dmapIt );

    void                                        displayLabel( DisplayableInterface *d );
273
    inline void                                 setLightRotationMatrix( const QMatrix4x4& m )   { m_View.lightRotationMatrix = m; update(); }
274 275 276 277 278

    void                                        repackDisplayables();

    void                                        manageAnimations();

279 280 281
    void                                        findObjectUnderCursor( const QPoint& cursor );
    void                                        clearObjectUnderCursor();

282 283
    QMatrix4x4                                  reframedProjection( float viewportX, float viewportY, float viewportW, float viewportH );

284 285
    void                                        processSelection( DisplayableInfo &dInfo, BaseSelectionProcessor &proc );

286 287 288
public:
	void	                                    init( DisplayDoF dof );

289 290 291
    inline void                                 getRenderState( RenderState& state ) const                      { state = m_View; }
    void                                        setRenderState( const RenderState& state );

292
    inline NavigationControl*                   navigationControl() const                                       { return m_NavigationCtrl.empty()? NULL : m_NavigationCtrl.front(); }
293 294 295
    void                                        pushNavigationControl( NavigationControl* ctrl );
    void                                        popNavigationControl();
    void                                        clearNavigationControlStack();
296

297
    inline QVector2D                            screenPosToClipCoord( const QPoint &screenPos )                 { return QVector2D( 2.0f*screenPos.x()/width()-1.0f, 1.0f-2.0f*screenPos.y()/height() ); }
298 299 300 301 302

    virtual void	                            initializeGL();
    void                                        paintGL();
	virtual void	                            resizeGL( int width, int height );

303
    void                                        setSelectionAllowed( bool allowed );
304
    inline bool                                 isSelectionAllowed() const                                      { return m_IsSelectionAllowed; }
305 306 307
    inline void                                 setParametersDisplayed( bool displayed )                        { ((QWidget*) m_DisplayOptionsLayout->parent())->setVisible( displayed ); }
    inline bool                                 areParametersDisplayed() const                                  { return ((QWidget*) m_DisplayOptionsLayout->parent())->isVisible(); }

308 309 310 311 312 313 314
    inline float                                speedFactor() const                                             { return m_SpeedFactor; }
    inline float                                ctrlSpeedFactor() const                                         { return m_CtrlSpeedFactor; }
    inline float                                shiftSpeedFactor() const                                        { return m_ShiftSpeedFactor; }

    inline const QVector3D&                     focusPoint() const                                              { return m_View.focusPoint; }
    inline float                                distToFocusPoint() const                                        { return m_View.distToFocusPoint; }
    inline float                                fovY() const                                                    { return m_View.fovY; }
315
    inline bool                                 isProjectionOrthographic() const                                { return m_View.isOrthographic; }
316 317 318 319 320 321 322 323 324 325 326 327
    inline double                               focal() const                                                   { return m_Focal; }
    inline float                                zNear() const                                                   { return m_View.zNear; }
    inline float                                zFar() const                                                    { return m_View.zFar; }
    inline float                                pointSize() const                                               { return m_View.pointSize; }
    inline DisplayDoF                           dof() const                                                     { return m_View.DoF; }

    inline const QMatrix4x4&                    projectionMatrix() const                                        { return m_ProjectionMatrix; }
    inline const QMatrix4x4&                    projectionMatrixInverse() const                                 { return m_ProjectionMatrixInverse; }
    inline const QMatrix4x4&                    viewMatrix() const                                              { return m_ViewMatrix; }
    inline const QMatrix4x4&                    viewMatrixInverse() const                                       { return m_ViewMatrixInverse; }
    inline const QMatrix4x4&                    viewRotationMatrix() const                                      { return m_View.viewRotationMatrix; }
    inline const QMatrix4x4&                    viewRotationMatrixInverse() const                               { return m_ViewRotationMatrixInverse; }
328
    QMatrix4x4                                  modelMatrix( const DisplayableInterface *d ) const;
329
    inline QMatrix4x4                           modelMatrixInverse( const DisplayableInterface *d ) const       { return modelMatrix(d).inverted(); }
330

331 332 333 334 335 336
    inline const QMatrix4x4&                    viewProjectionMatrix() const                                    { return m_ViewProjectionMatrix; }
    inline const QMatrix4x4&                    viewProjectionMatrixInverse() const                             { return m_ViewProjectionMatrixInverse; }
    inline QMatrix4x4                           modelViewMatrix( const DisplayableInterface *d ) const          { return viewMatrix() * modelMatrix(d); }
    inline QMatrix4x4                           modelViewMatrixInverse( const DisplayableInterface *d ) const   { return modelViewMatrix(d).inverted(); }
    inline QMatrix4x4                           MVPMatrix( const DisplayableInterface *d ) const                { return viewProjectionMatrix() * modelMatrix(d); }
    inline QMatrix4x4                           MVPMatrixInverse( const DisplayableInterface *d ) const         { return MVPMatrix(d).inverted(); }
337

338 339 340 341
    inline QVector3D                            rightAxis() const                                               { return  viewMatrix().row(0).toVector3D(); }
    inline QVector3D                            topAxis() const                                                 { return  viewMatrix().row(1).toVector3D(); }
    inline QVector3D                            frontAxis() const                                               { return -viewMatrix().row(2).toVector3D(); }

342 343
    inline const Frustum&                       frustum() const                                                 { return m_Frustum; }

344 345
    inline QVector3D                            viewpointLocation() const                                       { auto& R = viewMatrix(); return R.transposed().mapVector( -R.column(3).toVector3D() ); }
    void                                        pixelRay( int px, int py, QVector3D &rayOrig, QVector3D &rayDir ) const;
346
    QMatrix4x4                                  viewportMatrix( bool flipY = false ) const;
347 348
    inline QMatrix4x4                           normalMatrix( const DisplayableInterface *d ) const             { QMatrix4x4 m = modelViewMatrix(d); m(0,3) = m(1,3) = m(2,3) = 0.0f; return m; }
    inline const QMatrix4x4&                    lightRotationMatrix() const                                     { return m_View.lightRotationMatrix; }
349

350 351 352 353 354
    inline QVector3D                            lightDirection() const                                          { return m_View.lightRotationMatrix.column(2).toVector3D(); }
    inline bool                                 isLightingEnabled() const                                       { return m_View.isLightingEnabled;  }
    inline bool                                 isWireframeEnabled() const                                      { return m_View.isWireframeEnabled; }
    inline bool                                 isCullingEnabled() const                                        { return m_View.isCullingEnabled; }
    inline bool                                 isLightTrackingEye() const                                      { return m_View.isLightTrackingEnabled; }
355

356
    inline void                                 clearAllFactories()                                             { m_Factories.clear(); }
357 358 359 360 361 362 363 364 365
    void                                        populateDisplayerFactories( DisplayableFactoryInterface *plugin );
    void                                        populateDisplayerFactories( QList<DisplayableFactoryInterface*> &plugins );

    inline bool                                 isDisplayed( GenericUIData *m ) const           { return m_Displayables.find(m) != m_Displayables.end(); }
    inline bool                                 isAbleToDisplay( GenericUIData *m ) const       { return m_Factories.find(m->GetTypeString()) != m_Factories.end(); }
    inline DisplayableFactoryInterface*         getFactory( const QString &type )               { FactoryMap::iterator f=m_Factories.find(type); return f==m_Factories.end()? NULL : f->second; }
    inline const DisplayableFactoryInterface*   getFactory( const QString &type ) const         { FactoryMap::const_iterator f=m_Factories.find(type); return f==m_Factories.end()? NULL : f->second; }
    inline DisplayableInterface*                getDisplayable( const GenericUIData* m )        { DisplayableMap::iterator d=m_Displayables.find(m); return d==m_Displayables.end()? NULL : d->second.displayable; }
    inline DisplayableInterface*                getDisplayable( const GenericUIData* m ) const  { DisplayableMap::const_iterator d=m_Displayables.find(m); return d==m_Displayables.end()? NULL : d->second.displayable; }
366
    virtual void                                updateDisplayable( GenericUIData *m, bool resetSelectionManagers = true );
367 368
    inline const DisplayableMap&                getDisplayables() const { return m_Displayables; }
    inline DisplayableMap&                      getDisplayables()       { return m_Displayables; }
369
	bool										isDisplayableValid( DisplayableInterface *d ) const;
370 371 372 373 374 375 376 377 378
    void                                        setTransform( GenericUIData *m, const QMatrix4x4 &xf );

    virtual bool                                getPickedPoint( const float x,
                                                                const float y,
                                                                PickedPoint &picked,
                                                                bool accurate );

    void                                        frameBox( Box3f &box, const QMatrix4x4 *xf = NULL );
    virtual void                                frameItem( GenericUIData* item );
379
    virtual void                                frameItems( QList<GenericUIData*> &items );
380
    virtual void                                frameAll();
381
    Box3f                                       sceneBox() const;
382 383 384 385

    inline bool                                 isSelectionEnabled() const                      { return m_SelectionEnabled; }
    inline const SelectionTool&                 currentSelectionTool() const                    { return *m_SelectionCurrentTool; }
    void                                        processSelection( BaseSelectionProcessor &proc );
386
    void                                        processSelection( QList<BaseSelectionProcessor*> &procList );
387
    void                                        processSelection( GenericUIData *m, BaseSelectionProcessor &proc );
388
    void                                        processSelection( DisplayableInterface *d, BaseSelectionProcessor &proc );
389

390 391 392 393 394 395 396 397
    QVector2D                                   screenCoords( float x, float y, float z ) const;
    inline QVector2D                            screenCoords( const QVector3D &v ) const            { return screenCoords(v.x(),v.y(),v.z()); }

    inline void                                 renderText( const QVector2D &v, const QString &text, const QFont &font = QFont(), Qt::Alignment align = 0 ) { renderText(v.x(),v.y(),text,font,align); }
    inline void                                 renderText( const QVector3D &v, const QString &text, const QFont &font = QFont(), Qt::Alignment align = 0 ) { renderText(screenCoords(v),text,font,align); }
    inline void                                 renderText( float x, float y, float z, const QString &text, const QFont &font = QFont(), Qt::Alignment align = 0 ) { renderText(screenCoords(x,y,z),text,font,align); }
    void                                        renderText( float x, float y, const QString &text, const QFont &font = QFont(), Qt::Alignment align = 0 );

398 399 400

    bool                                        imageOfCurrentDisplay( const GenericUIData *m, QImage &renderResult );

401
	void										updateSelection( QList< GenericUIData*> selectedItems );
402 403 404 405 406 407 408 409 410 411 412 413 414 415

    /**************\
    | QT signal(s) |
    \**************/
signals:
    void                                        distToFocusPointChanged( const float d );
    void                                        fovYChanged( const float fovY );
    void                                        focusPointChanged( const QVector3D &p );
    void                                        viewRotationMatrixUpdated( const QMatrix4x4 &deltaRot );
    void                                        cullingToggled( const bool cullingEnabled );
    void                                        screenSpaceTranslation( const QVector2D &tra );
    void                                        wireframeToggled( const bool wireframeEnabled );
    void                                        lightingToggled( const bool lightingEnabled );
    void                                        lightTrackingToggled( const bool trackingEnabled );
416
    void                                        keyPressed( QKeyEvent *evt );
417
    void                                        dataSelected( GenericUIData *d, Qt::KeyboardModifiers modifiers );
418
    void                                        pointSizeChanged( unsigned int size );
419 420 421 422 423

    /************\
    | QT slot(s) |
    \************/
public slots:
424 425 426
    inline void                                 mustUpdateFocal()               { m_MustUpdateFocal = true; update(); }
    inline void                                 mustUpdateProjectionMatrix()    { m_MustUpdateProjectionMatrix = true; update(); }
    inline void                                 mustUpdateViewMatrix()          { m_MustUpdateViewMatrix = true; update(); }
427

428 429 430
    inline void                                 emitScreenSpaceTranslation( const QVector2D& tr) { emit screenSpaceTranslation(tr); }
    inline void                                 emitViewRotationMatrixUpdated( const QMatrix4x4 &r ) { emit viewRotationMatrixUpdated(r); }

431
    virtual DisplayableInterface*               addDisplayable( GenericUIData *m );
432 433 434
    virtual void                                removeDisplayable( GenericUIData *m );
    virtual void                                removeAllDisplayables();

435 436 437 438 439 440 441 442 443 444 445
    void                                        centerView();

    void                                        setSpeedFactor( const float speedFactor,
                                                                const float ctrlSpeedFactor,
                                                                const float shiftSpeedFactor );
    void                                        setSpeedFactor( const float speedFactor );
    void                                        setCtrlSpeedFactor( const float ctrlSpeedFactor );
    void                                        setShiftSpeedFactor( const float shiftSpeedFactor );

    void                                        increasePointSize();
    void                                        decreasePointSize();
446
    void                                        setPointSize( unsigned int size );
447 448 449 450 451

    void                                        setFocusPoint( const QVector3D& p );
    void                                        setDistToFocusPoint( const float d );
    void                                        setViewRotationMatrix( const QMatrix4x4& m );
    void                                        setFovY( float fovY );
452
    void                                        setOrthographic( bool ortho );
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473

    void                                        setSelectionEnabled( bool enabled );
    void                                        setSelectionDisabled( bool disabled );
    void                                        toggleSelection();
    void                                        updateSelectionZBuffer();
    void                                        setSelectionEntity( SelectableEntity entity );
    void                                        clearSelection( SelectableEntity entities );
    void                                        updateSelection( SelectionTool &tool );

    void                                        setCullingEnabled( const bool enabled );
    void                                        toggleCulling();

    void                                        setWireframeEnabled( const bool enabled );
    void                                        setLightingEnabled( const bool enabled );
    void                                        setLightTrackingEnabled( const bool enabled );
    void                                        toggleWireframe();
    void                                        toggleLighting();
    void                                        toggleLightTracking();

    inline void                                 registerAnimation( DisplayableInterface *anim )     { m_AnimationStartingQueue.push_back( anim ); update(); }
    inline void                                 unregisterAnimation( DisplayableInterface *anim )   { m_AnimationStoppingQueue .push_back( anim ); update(); }
474 475 476

    inline void                                 setMetricGrid2DSuffix( const QString& suffix )      { s_MetricGrid2DSuffix = suffix; }
    inline void                                 setMetricGrid3DSuffix( const QString& suffix )      { s_MetricGrid3DSuffix = suffix; }
477 478 479

    void                                        setDemoModeEnabled( bool enabled );
    inline void                                 setDemoModeDisabled( bool disabled )                { setDemoModeEnabled( !disabled ); }
480 481 482 483 484 485
};




#endif //GLVIEWER_H