438 lines
18 KiB
C++

/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) 2010-2011, Willow Garage, Inc.
* Copyright (c) 2012-, Open Perception, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*
*/
#pragma once
#include <pcl/visualization/common/actor_map.h>
#include <pcl/visualization/common/ren_win_interact_map.h>
#include <pcl/visualization/keyboard_event.h>
#include <pcl/visualization/mouse_event.h>
#include <pcl/visualization/point_picking_event.h>
#include <pcl/visualization/area_picking_event.h>
#include <boost/signals2/signal.hpp>
#include <vtkInteractorStyleRubberBandPick.h>
#include <vtkRendererCollection.h>
#include <vtkRenderWindow.h>
class vtkRendererCollection;
class vtkLegendScaleActor;
class vtkScalarBarActor;
class vtkPNGWriter;
class vtkWindowToImageFilter;
class vtkPointPicker;
namespace pcl
{
namespace visualization
{
/** \brief A list of potential keyboard modifiers for \ref pcl::visualization::PCLVisualizerInteractorStyle::PCLVisualizerInteractorStyle()
* Defaults to Alt.
*/
enum InteractorKeyboardModifier
{
INTERACTOR_KB_MOD_ALT,
INTERACTOR_KB_MOD_CTRL,
INTERACTOR_KB_MOD_SHIFT
};
/** \brief PCLVisualizerInteractorStyle defines an unique, custom VTK
* based interactory style for PCL Visualizer applications. Besides
* defining the rendering style, we also create a list of custom actions
* that are triggered on different keys being pressed:
*
* - p, P : switch to a point-based representation
* - w, W : switch to a wireframe-based representation (where available)
* - s, S : switch to a surface-based representation (where available)
* - j, J : take a .PNG snapshot of the current window view
* - c, C : display current camera/window parameters
* - f, F : fly to point mode
* - e, E : exit the interactor\
* - q, Q : stop and call VTK's TerminateApp
* - + / - : increment/decrement overall point size
* - g, G : display scale grid (on/off)
* - u, U : display lookup table (on/off)
* - r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]
* - CTRL + s, S : save camera parameters
* - CTRL + r, R : restore camera parameters
* - ALT + s, S : turn stereo mode on/off
* - ALT + f, F : switch between maximized window mode and original size
* - l, L : list all available geometric and color handlers for the current actor map
* - ALT + 0..9 [+ CTRL] : switch between different geometric handlers (where available)
* - 0..9 [+ CTRL] : switch between different color handlers (where available)
* -
* - SHIFT + left click : select a point
* - x, X : toggle rubber band selection mode for left mouse button
*
* \author Radu B. Rusu
* \ingroup visualization
*/
class PCL_EXPORTS PCLVisualizerInteractorStyle : public vtkInteractorStyleRubberBandPick
{
public:
using CloudActorMapPtr = pcl::visualization::CloudActorMapPtr;
static PCLVisualizerInteractorStyle *New ();
/** \brief Empty constructor. */
PCLVisualizerInteractorStyle () :
init_ (), win_height_ (), win_width_ (), win_pos_x_ (), win_pos_y_ (),
max_win_height_ (), max_win_width_ (), use_vbos_ (false), grid_enabled_ (), lut_enabled_ (),
stereo_anaglyph_mask_default_ (),
modifier_ (), camera_saved_ (), lut_actor_id_ ("")
{}
/** \brief Empty destructor */
~PCLVisualizerInteractorStyle () {}
// this macro defines Superclass, the isA functionality and the safe downcast method
vtkTypeMacro (PCLVisualizerInteractorStyle, vtkInteractorStyleRubberBandPick);
/** \brief Initialization routine. Must be called before anything else. */
virtual void
Initialize ();
/** \brief Pass a pointer to the cloud actor map
* \param[in] actors the actor map that will be used with this style
*/
inline void
setCloudActorMap (const CloudActorMapPtr &actors) { cloud_actors_ = actors; }
/** \brief Pass a pointer to the shape actor map
* \param[in] actors the actor map that will be used with this style
*/
inline void
setShapeActorMap (const ShapeActorMapPtr &actors) { shape_actors_ = actors; }
/** \brief Get the cloud actor map pointer. */
inline CloudActorMapPtr
getCloudActorMap () { return (cloud_actors_); }
/** \brief Get the cloud actor map pointer. */
inline ShapeActorMapPtr
getShapeActorMap () { return (shape_actors_); }
/** \brief Pass a set of renderers to the interactor style.
* \param[in] rens the vtkRendererCollection to use
*/
void
setRendererCollection (vtkSmartPointer<vtkRendererCollection> &rens) { rens_ = rens; }
/** \brief Use Vertex Buffer Objects renderers.
* This is an optimization for the obsolete OpenGL backend. Modern OpenGL2 backend (VTK ≥ 6.3) uses vertex
* buffer objects by default, transparently for the user.
* \param[in] use_vbos set to true to use VBOs
*/
inline void
setUseVbos (const bool use_vbos) { use_vbos_ = use_vbos; }
/** \brief Register a callback function for mouse events
* \param[in] cb a std function that will be registered as a callback for a mouse event
* \return a connection object that allows to disconnect the callback function.
*/
boost::signals2::connection
registerMouseCallback (std::function<void (const pcl::visualization::MouseEvent&)> cb);
/** \brief Register a callback std::function for keyboard events
* \param[in] cb a std function that will be registered as a callback for a keyboard event
* \return a connection object that allows to disconnect the callback function.
*/
boost::signals2::connection
registerKeyboardCallback (std::function<void (const pcl::visualization::KeyboardEvent&)> cb);
/** \brief Register a callback function for point picking events
* \param[in] cb a std function that will be registered as a callback for a point picking event
* \return a connection object that allows to disconnect the callback function.
*/
boost::signals2::connection
registerPointPickingCallback (std::function<void (const pcl::visualization::PointPickingEvent&)> cb);
/** \brief Register a callback function for area picking events
* \param[in] cb a std function that will be registered as a callback for a area picking event
* \return a connection object that allows to disconnect the callback function.
*/
boost::signals2::connection
registerAreaPickingCallback (std::function<void (const pcl::visualization::AreaPickingEvent&)> cb);
/** \brief Save the current rendered image to disk, as a PNG screenshot.
* \param[in] file the name of the PNG file
*/
void
saveScreenshot (const std::string &file);
/** \brief Save the camera parameters to disk, as a .cam file.
* \param[in] file the name of the .cam file
*/
bool
saveCameraParameters (const std::string &file);
/** \brief Get camera parameters of a given viewport (0 means default viewport). */
void
getCameraParameters (Camera &camera, int viewport = 0) const;
/** \brief Load camera parameters from a camera parameter file.
* \param[in] file the name of the camera parameter file
*/
bool
loadCameraParameters (const std::string &file);
/** \brief Set the camera parameters via an intrinsics and and extrinsics matrix
* \note This assumes that the pixels are square and that the center of the image is at the center of the sensor.
* \param[in] intrinsics the intrinsics that will be used to compute the VTK camera parameters
* \param[in] extrinsics the extrinsics that will be used to compute the VTK camera parameters
* \param[in] viewport the viewport to modify camera of (0 modifies all cameras)
*/
void
setCameraParameters (const Eigen::Matrix3f &intrinsics, const Eigen::Matrix4f &extrinsics, int viewport = 0);
/** \brief Set the camera parameters by given a full camera data structure.
* \param[in] camera camera structure containing all the camera parameters.
* \param[in] viewport the viewport to modify camera of (0 modifies all cameras)
*/
void
setCameraParameters (const Camera &camera, int viewport = 0);
/** \brief Set camera file for camera parameter saving/restoring.
* \param[in] file the name of the camera parameter file
*/
void
setCameraFile (const std::string file)
{
camera_file_ = file;
}
/** \brief Get camera file for camera parameter saving/restoring. */
std::string
getCameraFile () const
{
return (camera_file_);
}
/** \brief Change the default keyboard modified from ALT to a different special key.
* Allowed values are:
* - INTERACTOR_KB_MOD_ALT
* - INTERACTOR_KB_MOD_CTRL
* - INTERACTOR_KB_MOD_SHIFT
* \param[in] modifier the new keyboard modifier
*/
inline void
setKeyboardModifier (const InteractorKeyboardModifier &modifier)
{
modifier_ = modifier;
}
protected:
/** \brief Set to true after initialization is complete. */
bool init_;
/** \brief Collection of vtkRenderers stored internally. */
vtkSmartPointer<vtkRendererCollection> rens_;
/** \brief Cloud actor map stored internally. */
CloudActorMapPtr cloud_actors_;
/** \brief Shape map stored internally. */
ShapeActorMapPtr shape_actors_;
/** \brief The current window width/height. */
int win_height_, win_width_;
/** \brief The current window position x/y. */
int win_pos_x_, win_pos_y_;
/** \brief The maximum resizeable window width/height. */
int max_win_height_, max_win_width_;
/** \brief Boolean that holds whether or not to use the vtkVertexBufferObjectMapper*/
bool use_vbos_;
/** \brief Set to true if the grid actor is enabled. */
bool grid_enabled_;
/** \brief Actor for 2D grid on screen. */
vtkSmartPointer<vtkLegendScaleActor> grid_actor_;
/** \brief Set to true if the LUT actor is enabled. */
bool lut_enabled_;
/** \brief Actor for 2D lookup table on screen. */
vtkSmartPointer<vtkScalarBarActor> lut_actor_;
/** \brief A PNG writer for screenshot captures. */
vtkSmartPointer<vtkPNGWriter> snapshot_writer_;
/** \brief Internal window to image filter. Needed by \a snapshot_writer_. */
vtkSmartPointer<vtkWindowToImageFilter> wif_;
/** \brief Stores the point picker when switching to an area picker. */
vtkSmartPointer<vtkPointPicker> point_picker_;
boost::signals2::signal<void (const pcl::visualization::MouseEvent&)> mouse_signal_;
boost::signals2::signal<void (const pcl::visualization::KeyboardEvent&)> keyboard_signal_;
boost::signals2::signal<void (const pcl::visualization::PointPickingEvent&)> point_picking_signal_;
boost::signals2::signal<void (const pcl::visualization::AreaPickingEvent&)> area_picking_signal_;
/** \brief Interactor style internal method. Gets called whenever a key is pressed. */
void
OnChar () override;
// Keyboard events
void
OnKeyDown () override;
void
OnKeyUp () override;
// mouse button events
void
OnMouseMove () override;
void
OnLeftButtonDown () override;
void
OnLeftButtonUp () override;
void
OnMiddleButtonDown () override;
void
OnMiddleButtonUp () override;
void
OnRightButtonDown () override;
void
OnRightButtonUp () override;
void
OnMouseWheelForward () override;
void
OnMouseWheelBackward () override;
// mouse move event
/** \brief Interactor style internal method. Gets called periodically if a timer is set. */
void
OnTimer () override;
/** \brief Interactor style internal method. Zoom in. */
void
zoomIn ();
/** \brief Interactor style internal method. Zoom out. */
void
zoomOut ();
/** \brief Get camera parameters from a string vector.
* \param[in] camera A string vector:
* Clipping Range, Focal Point, Position, ViewUp, Distance, Field of View Y, Window Size, Window Pos.
* Values in each string are separated by a ','
*/
bool
getCameraParameters (const std::vector<std::string> &camera);
/** \brief Set render window. */
void
setRenderWindow (const vtkSmartPointer<vtkRenderWindow> &win)
{
win_ = win;
}
/** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */
bool stereo_anaglyph_mask_default_;
/** \brief A VTK Mouse Callback object, used for point picking. */
vtkSmartPointer<PointPickingCallback> mouse_callback_;
/** \brief The keyboard modifier to use. Default: Alt. */
InteractorKeyboardModifier modifier_;
/** \brief Camera file for camera parameter saving/restoring. */
std::string camera_file_;
/** \brief A \ref pcl::visualization::Camera for camera parameter saving/restoring. */
Camera camera_;
/** \brief A \ref pcl::visualization::Camera is saved or not. */
bool camera_saved_;
/** \brief The render window.
* Only used when interactor maybe not available
*/
vtkSmartPointer<vtkRenderWindow> win_;
friend class PointPickingCallback;
friend class PCLVisualizer;
private:
/** \brief ID used to fetch/display the look up table on the visualizer
* It should be set by PCLVisualizer \ref setLookUpTableID
* @note If empty, a random actor added to the interactor will be used */
std::string lut_actor_id_;
/** \brief Add/remove the look up table displayed when 'u' is pressed, can also be used to update the current LUT displayed
* \ref lut_actor_id_ is used (if not empty) to chose which cloud/shape actor LUT will be updated (depending on what is available)
* If \ref lut_actor_id_ is empty the first actor with LUT support found will be used. */
void
updateLookUpTableDisplay (bool add_lut = false);
};
/** \brief PCL histogram visualizer interactory style class.
* \author Radu B. Rusu
*/
class PCLHistogramVisualizerInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static PCLHistogramVisualizerInteractorStyle *New ();
/** \brief Empty constructor. */
PCLHistogramVisualizerInteractorStyle () : init_ (false) {}
/** \brief Initialization routine. Must be called before anything else. */
void
Initialize ();
/** \brief Pass a map of render/window/interactors to the interactor style.
* \param[in] wins the RenWinInteract map to use
*/
void
setRenWinInteractMap (const RenWinInteractMap &wins) { wins_ = wins; }
private:
/** \brief A map of all windows on screen (with their renderers and interactors). */
RenWinInteractMap wins_;
/** \brief Set to true after initialization is complete. */
bool init_;
/** \brief Interactor style internal method. Gets called whenever a key is pressed. */
void OnKeyDown () override;
/** \brief Interactor style internal method. Gets called periodically if a timer is set. */
void OnTimer () override;
};
}
}