@ken-martin @utkarshayachit There is no way to listen to LeftButtonReleaseEvent
on an interactor.
A quick google search shows up this, http://vtk.1045678.n5.nabble.com/Mouse-button-release-event-is-still-broken-in-VTK-6-0-0-td5724762.html thread. It’s sort of dead since 2013.
The workaround is
iStyle = interactor->GetInteractorStyle()->GetCurrentStyle()
iStyle->HandleObserversOn();
iStyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, ...)
The first line gets a bit complicated if the interactor is not using vtkInteractorStyleSwitch
. It gets all the more complicated when you start pressing the ‘c’, ‘a’, ‘t’, ‘j’ keys. Those shortcut keys switch the style itself, so it would require detaching the observers on the old interactor style and reattaching to the newer interactor style. One would end up making a class to handle this complication for all events.
I attached the callback to the HelloWorld vtk example, it doesn’t print “Left Release”.
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCallbackCommand.h>
#include <vtkCylinderSource.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <array>
void Callback(vtkObject* caller, unsigned long ev, void* clientdata, void* calldata) {
switch (ev)
{
case vtkCommand::LeftButtonPressEvent:
std::cout << "Left Press\n";
break;
case vtkCommand::LeftButtonReleaseEvent:
std::cout << "Left Release\n";
break;
default:
break;
}
}
int main(int, char* [])
{
vtkNew<vtkNamedColors> colors;
// Set the background color.
std::array<unsigned char, 4> bkg{ {26, 51, 102, 255} };
colors->SetColor("BkgColor", bkg.data());
// This creates a polygonal cylinder model with eight circumferential facets
// (i.e, in practice an octagonal prism).
vtkNew<vtkCylinderSource> cylinder;
cylinder->SetResolution(8);
// The mapper is responsible for pushing the geometry into the graphics
// library. It may also do color mapping, if scalars or other attributes are
// defined.
vtkNew<vtkPolyDataMapper> cylinderMapper;
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
// The actor is a grouping mechanism: besides the geometry (mapper), it
// also has a property, transformation matrix, and/or texture map.
// Here we set its color and rotate it around the X and Y axes.
vtkNew<vtkActor> cylinderActor;
cylinderActor->SetMapper(cylinderMapper);
cylinderActor->GetProperty()->SetColor(
colors->GetColor4d("Tomato").GetData());
cylinderActor->RotateX(30.0);
cylinderActor->RotateY(-45.0);
// The renderer generates the image
// which is then displayed on the render window.
// It can be thought of as a scene to which the actor is added
vtkNew<vtkRenderer> renderer;
renderer->AddActor(cylinderActor);
renderer->SetBackground(colors->GetColor3d("BkgColor").GetData());
// Zoom in a little by accessing the camera and invoking its "Zoom" method.
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(1.5);
// The render window is the actual GUI window
// that appears on the computer screen
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->SetSize(300, 300);
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("Cylinder");
// The render window interactor captures mouse events
// and will perform appropriate camera or actor manipulation
// depending on the nature of the events.
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
// This starts the event loop and as a side effect causes an initial render.
vtkNew<vtkCallbackCommand> lbtnCb;
lbtnCb->SetCallback(Callback);
renderWindowInteractor->AddObserver(vtkCommand::LeftButtonPressEvent, lbtnCb);
renderWindowInteractor->AddObserver(vtkCommand::LeftButtonReleaseEvent, lbtnCb);
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
project(CylinderExample)
find_package(VTK COMPONENTS
vtkCommonColor
vtkCommonCore
vtkFiltersSources
vtkInteractionStyle
vtkRenderingContextOpenGL2
vtkRenderingCore
vtkRenderingFreeType
vtkRenderingGL2PSOpenGL2
vtkRenderingOpenGL2
QUIET
)
if (NOT VTK_FOUND)
message("Skipping CylinderExample: ${VTK_NOT_FOUND_MESSAGE}")
return ()
endif()
message (STATUS "VTK_VERSION: ${VTK_VERSION}")
if (VTK_VERSION VERSION_LESS "8.90.0")
# old system
include(${VTK_USE_FILE})
add_executable(CylinderExample MACOSX_BUNDLE CylinderExample.cxx )
target_link_libraries(CylinderExample PRIVATE ${VTK_LIBRARIES})
else ()
# include all components
add_executable(CylinderExample MACOSX_BUNDLE CylinderExample.cxx )
target_link_libraries(CylinderExample PRIVATE ${VTK_LIBRARIES})
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS CylinderExample
MODULES ${VTK_LIBRARIES}
)
endif ()