Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend viewer3 d #1259

Merged
merged 11 commits into from
Apr 8, 2017
6 changes: 4 additions & 2 deletions .travis/install_deps_macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
# Note: gmp and boost already installed
#
brew update
#brew install qt5 doxygen homebrew/science/hdf5 graphviz graphicsmagick fftw eigen homebrew/boneyard/libqglviewer
brew install qt5 graphicsmagick fftw eigen homebrew/boneyard/libqglviewer
#brew install qt5 doxygen homebrew/science/hdf5 graphviz graphicsmagick fftw eigen
brew install qt5 graphicsmagick fftw eigen
# Explicit install of libqglviewer
brew install http://liris.cnrs.fr/david.coeurjolly/misc/libqglviewer.rb

## Temporary HDF5 build issue
export BTYPE="$BTYPE -DWITH_HDF5=false" && echo "Disabling HDF5 on MacOS";
Expand Down
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## New Features / Critical Changes

- *IO*
- New simple way to extend the QGLViewer-based Viewer3D interface,
for instance to add callbacks to key or mouse events, or to modify
what is drawn on the window.
(Jacques-Olivier Lachaud, [#1259](https://github.com/DGtal-team/DGtal/pull/1259))

## Changes

Expand Down
1 change: 1 addition & 0 deletions examples/io/viewers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ SET(DGTAL_TESTS_SRC
viewer3D-7bis-planes
viewer3D-9-3Dimages
viewer3D-10-interaction
viewer3D-11-extension
demo-kernel-2
)

Expand Down
132 changes: 132 additions & 0 deletions examples/io/viewers/viewer3D-11-extension.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
**/

/**
* @file io/viewers/viewer3D-11-extension.cpp
* @ingroup examples/3dViewer
* @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
* Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
*
* @date 2017/03/05
*
* Simple example of class Viewer3D.
*
* This file is part of the DGtal library.
*/

/**
* Example of extension of Viewer3D interface by deriving the class
* Viewer3D::Extension. Here we have added a callback to the
* "Shift+R" keypressed event, which adds a point randomly in the domain.
*
* @see moduleQGLExtension
* \example io/viewers/viewer3D-11-extension.cpp
* \image html simple3dVisu1.png "Extending the Viewer3D interface: just press Shift+R and you have new points added randomly in the scene."
*/

///////////////////////////////////////////////////////////////////////////////
#include <iostream>

#include "DGtal/base/Common.h"
#include "DGtal/helpers/StdDefs.h"
#include "DGtal/io/viewers/Viewer3D.h"
///////////////////////////////////////////////////////////////////////////////

using namespace std;
using namespace DGtal;
using namespace Z3i;


///////////////////////////////////////////////////////////////////////////////
// Standard services - public :


//! [viewer3D-extension-derivation]
// 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 ) )
{
typedef Viewer::KSpace KSpace;
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;
viewer << Viewer::updateDisplay;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this example, the updateDisplay resets the camera settings .. which is a bit odd..
Maybe this could be fixed in the Viewer3D, @kerautret, any idea?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, updateDisplay call updateList with the update of the boundingbox (looks natural in classical use) but with this nice extension is should be better to add a new something like Viewer::updateDisplayFix which is equivalent but with no update.
Else you can simply equivalently call viewer.updateList(false); instead Viewer::updateDisplay; and you will have it ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I applied an improvement to avoid to add new display options, @JacquesOlivierLachaud I PR it on your branch: it checked if the BB has changed and it changed camera position only if the BB changed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kerautret With your PR, do I have now to call viewer.updateList(false); instead of Viewer::updateDisplay ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessary in your example the BB don't change so the camera will not move. And in other cases it is looks fine if the BB scene change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I fix David's comment and the PR will be ready.

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;
}

};
//! [viewer3D-extension-derivation]

int main( int argc, char** argv )
{

QApplication application(argc,argv);

Point p1( 0, 0, 0 );
Point p2( 5, 5 ,5 );
Point p3( 2, 3, 4 );
Domain domain( p1, p2 );

typedef Viewer3D<> MyViewer;
KSpace K;
K.init( p1, p2, true );
//! [viewer3D-extension-set-extension]
MyViewer viewer( K );
viewer.setExtension( new RandomPointKeyExtension );
//! [viewer3D-extension-set-extension]
viewer.show();
viewer << domain;
viewer << p1 << p2 << p3;

viewer<< MyViewer::updateDisplay;
return application.exec();
}
// //
///////////////////////////////////////////////////////////////////////////////
2 changes: 2 additions & 0 deletions src/DGtal/io/Display3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,8 @@ namespace DGtal
///
std::set<SelectCallbackFctStore> mySelectCallBackFcts;

bool myBoundingPtChangedTag = false;

//----end of protected datas

// ------------------------- Internals ------------------------------------
Expand Down
40 changes: 33 additions & 7 deletions src/DGtal/io/Display3D.ih
Original file line number Diff line number Diff line change
Expand Up @@ -1191,16 +1191,42 @@ DGtal::Display3D< Space ,KSpace >::updateBoundingBox(const RealPoint &p)
myBoundingPtUp[1]= p[1];
myBoundingPtUp[2]= p[2];
myBoundingPtEmptyTag = false;
myBoundingPtChangedTag = true;
}
else
{
if(p[0] <myBoundingPtLow[0]) myBoundingPtLow[0]= p[0];
if(p[1] <myBoundingPtLow[1]) myBoundingPtLow[1]= p[1];
if(p[2] <myBoundingPtLow[2]) myBoundingPtLow[2]= p[2];

if(p[0] >myBoundingPtUp[0]) myBoundingPtUp[0]= p[0];
if(p[1] >myBoundingPtUp[1]) myBoundingPtUp[1]= p[1];
if(p[2] >myBoundingPtUp[2]) myBoundingPtUp[2]= p[2];
if(p[0] <myBoundingPtLow[0])
{
myBoundingPtLow[0]= p[0];
myBoundingPtChangedTag = true;
}
if(p[1] <myBoundingPtLow[1])
{
myBoundingPtLow[1]= p[1];
myBoundingPtChangedTag = true;
}

if(p[2] <myBoundingPtLow[2])
{
myBoundingPtLow[2]= p[2];
myBoundingPtChangedTag = true;
}

if(p[0] >myBoundingPtUp[0])
{
myBoundingPtUp[0]= p[0];
myBoundingPtChangedTag = true;
}
if(p[1] >myBoundingPtUp[1])
{
myBoundingPtUp[1]= p[1];
myBoundingPtChangedTag = true;
}
if(p[2] >myBoundingPtUp[2])
{
myBoundingPtUp[2]= p[2];
myBoundingPtChangedTag = true;
}
}
}

Expand Down
88 changes: 88 additions & 0 deletions src/DGtal/io/doc/moduleQGLExtension.dox
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@


/*
* Useful to avoid writing DGtal:: in front of every class.
*/
namespace DGtal {

/**
* @page moduleQGLExtension 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: \ref moduleQGLInteraction
*
* [TOC]
*
* \section QGLExtension_sec1 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:
*
* - Viewer3D::Extension::keyPressEvent. This method may be
* overloaded to capture other key events.
*
* - Viewer3D::Extension::drawWithNames. This method is useful for
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting.. would you have an example of that ?

Copy link
Member Author

@JacquesOlivierLachaud JacquesOlivierLachaud Apr 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used indirectly in the mini-interaction method, see for instance
https://github.com/DGtal-team/DGtal/blob/master/examples/io/viewers/viewer3D-10-interaction.cpp
I do not have a useful example here for overriding it, but it was natural to provide ways to override all the standard methods provided by libQGLViewer.

* drawing elements with additional information for selection (see also \ref moduleQGLInteraction).
*
* - Viewer3D::Extension::draw. This method is useful for drawing elements that are not directly handled by Viewer3D.
*
* - Viewer3D::Extension::init. This method is useful at initialization (e.g. adding lights manipulators).
*
* - Viewer3D::Extension::helpString. This method is useful to change the help message.
*
* - Viewer3D::Extension::postSelection. This method is useful to take
* care of mouse selection events.
*
* - Viewer3D::Extension::mouseMoveEvent. This method is useful to
* take care of mouse movements.
*
* - Viewer3D::Extension::mousePressEvent. This method is useful to
* take care of mouse button press events.
*
* - Viewer3D::Extension::mouseReleaseEvent. This method is useful to
* take care of mouse button release events.
*
* 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.
*
* @snippet io/viewers/viewer3D-11-extension.cpp viewer3D-extension-derivation
*
* \section QGLExtension_sec2 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.
*
* @snippet io/viewers/viewer3D-11-extension.cpp viewer3D-extension-set-extension
*
* The viewer will take care of freeing your instanciated extension object.
* For a complete example, see viewer3D-11-extension.cpp.
*/

}
1 change: 1 addition & 0 deletions src/DGtal/io/doc/packageIO.dox
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ In this package, we present DGtal tools and utilities to import/export images an
- \ref moduleBoard2D (Jacques-Olivier Lachaud, Nicolas Normand, David Coeurjolly, Martial Tola)
- \ref moduleDisplay3D (Bertrand Kerautret, Martial Tola, Aline Martin, David Coeurjolly)
- \ref moduleQGLInteraction (Jacques-Olivier Lachaud, Bertrand Kerautret)
- \ref moduleQGLExtension (Jacques-Olivier Lachaud)
- \ref moduleIO (David Coeurjolly, Bertrand Kerautret, Martial Tola, Pierre Gueth)

@b Package @b Concepts @b Overview
Expand Down
Loading