DGtal  1.4.2
Extending the QGLViewer Viewer3D interface

This part of the manual describes how to extend the standard Viewer3D interface of DGtal. For instance, you wish to assign new handlers keys or to mouse event, or you wish to display or select other graphical elements. To do that, you just have to write a class that derived from Viewer3D::Extension and overrides some methods to get your desired behaviour.

Author
Jacques-Olivier Lachaud
Since
9.4

Related examples: viewer3D-11-extension.cpp

Related modules: Limited interaction when using selection with QGLViewer Viewer3D stream mechanism

Extending the standard behavior of Viewer3D

The Viewer3D interface provides a very handy way of visualising 3D scenes, digital objects or meshes in DGtal, and is bundled with many functionalities (like moving the light, selecting some objects, etc). However it is not directly extensible as is, and, for several reasons, you cannot derive from the Viewer3D class directly to add some new functionalities.

Therefore we provide the class Viewer3D::Extension so that you can extend the viewer in several ways. The principle is very easy. This interface provides a set of empty virtual methods so you just have to override them in order to change the behavior of the viewer. For instance, you just have to override Viewer3D::Extension::keyPressEvent to capture other key events. You can override all the following methods:

The example below shows how to capture "Shift+R" key pressed events, so that each time this event occurs random points are added to the 3D scene.

// Deriving from Viewer3D::Extension to add new callbacks to events.
struct RandomPointKeyExtension : public Viewer3D<Space, KSpace>::Extension
{
RandomPointKeyExtension()
{
}
// Here we override the "key pressed" event, and a point randomly in
// the scene if the key "Shift+R" is pressed.
virtual bool keyPressEvent( Viewer & viewer, QKeyEvent * event )
{
bool handled = false;
// Get event modifiers key
const Qt::KeyboardModifiers modifiers = event->modifiers();
if ( ( event->key() == Qt::Key_R ) && ( modifiers == Qt::ShiftModifier ) )
{
Point p = viewer.space().lowerBound();
Point q = viewer.space().upperBound();
Point d = q - p;
Point a( ( rand() % d[ 0 ] ) + p[ 0 ], ( rand() % d[ 1 ] ) + p[ 1 ],
( rand() % d[ 2 ] ) + p[ 2 ] );
viewer << a;
trace.info() << "Adding point " << a << std::endl;
handled = true;
}
return handled;
}
// We also override the Viewer3D::init method to add a key
// description in the help window.
virtual void init( Viewer & viewer )
{
viewer.setKeyDescription( Qt::ShiftModifier + Qt::Key_R,
"Creates a random digital point." );
}
// We also override the Viewer3D::helpString method to add a
// description to the viewer.
virtual QString helpString( const Viewer & /*viewer*/ ) const
{
QString text( "<h2> Random point Viewer3D </h2>" );
text += "Press Shift+R to add points.";
return text;
}
};
const KSpace & space() const
Definition: Display3D.h:340
std::ostream & info()
Trace trace
Definition: Common.h:153
MyPointD Point
Definition: testClone2.cpp:383
K init(Point(0, 0, 0), Point(512, 512, 512), true)

Activating your extension in some viewer

Once you have built a class that derives from Viewer3D::Extension, it remains to create some instance of this extension and to hand it to your viewer. This is done by the following lines.

MyViewer viewer( K );
viewer.setExtension( new RandomPointKeyExtension );
void setExtension(Extension *ext)
Definition: Viewer3D.h:312
KSpace K

The viewer will take care of freeing your instanciated extension object. For a complete example, see viewer3D-11-extension.cpp.