VTK Mouse Picking
The default way to pick a cell/point/actor under the cursor in a render window is to press the "p" key. You may prefer to pick by pressing a mouse button. The problem is most interactor styles have already assigned functions to the mouse buttons such as rotating the camera or actor. This method of picking with a mouse button uses the fact that in vtkInteractorStyleTrackballCamera you must move the mouse in addition to pressing a mouse button to interact with the scene. Below is a tcl example of how to change vtkInteractorStyleTrackballCamera so that when you press the left mouse button and release it without moving the mouse you will perform a pick under the cursor.
The annotatePick.tcl example is modifed below to illustrate a working example but here is the pertinent code:
vtkInteractorStyleTrackballCamera style style AddObserver LeftButtonPressEvent {set MouseMotion 0; style OnLeftButtonDown} style AddObserver MouseMoveEvent {set MouseMotion 1; style OnMouseMove} style AddObserver LeftButtonReleaseEvent cbLBR proc cbLBR {} { if {$::MouseMotion == 0} { eval picker Pick [iren GetEventPosition] 0 ren1 } }
A "MouseMotion" flag is set to "0" when the left button is pressed. This flag is changed to "1" when you move the mouse. When you release the left button, the callback "cbLBR" checks "MouseMotion" to see if you have moved the mouse and performs a pick if you haven't.
I have a c++ implimentation of this that also allows you to turn mouse picking on/off and to get which mouse button was pressed. I'll post it as an idea to the bug tracker with a patch to vtkInteractorStyleTrackballCamera... here's the link Bug submission. (You could use this with vtkInteractorStyleTrackballActor too)
--Goodwin 15:11, 12 Aug 2004 (EDT)
As of 6th May 2005 CVS (for tcl bindings), you can use a double click of a mouse button to pick. In tcl you could have:
vtkInteractorStyleTrackballCamera style style AddObserver LeftButtonReleaseEvent cbLBR style AddObserver LeftButtonReleaseEvent {style OnLeftButtonUp} proc cbLBR {} { if {[iren GetRepeatCount] == 1} { eval picker Pick [iren GetEventPosition] 0 ren1 } }
For a double click the iren's RepeatCount var is set to 1. For a single click it's set to 0.
Here's the full example (modified annotatePick.tcl):
To perform a pick in the example below: move the cursor to the position in the render window you want to pick, then press and release the left mouse button without moving the mouse in between. This may seem tricky at first but you'll get used to it!
# This example demonstrates cell picking using vtkCellPicker. It displays # the results of picking using a vtkTextMapper. # # First we include the VTK Tcl packages which will make available # all of the vtk commands to Tcl # package require vtk package require vtkinteraction # create a sphere source, mapper, and actor # vtkSphereSource sphere vtkPolyDataMapper sphereMapper sphereMapper SetInput [sphere GetOutput] sphereMapper GlobalImmediateModeRenderingOn vtkLODActor sphereActor sphereActor SetMapper sphereMapper # create the spikes by glyphing the sphere with a cone. Create the mapper # and actor for the glyphs. vtkConeSource cone vtkGlyph3D glyph glyph SetInput [sphere GetOutput] glyph SetSource [cone GetOutput] glyph SetVectorModeToUseNormal glyph SetScaleModeToScaleByVector glyph SetScaleFactor 0.25 vtkPolyDataMapper spikeMapper spikeMapper SetInput [glyph GetOutput] vtkLODActor spikeActor spikeActor SetMapper spikeMapper # Create a cell picker. vtkCellPicker picker picker AddObserver EndPickEvent annotatePick # Create a text mapper and actor to display the results of picking. vtkTextMapper textMapper set tprop [textMapper GetTextProperty] $tprop SetFontFamilyToArial $tprop SetFontSize 10 $tprop BoldOn $tprop ShadowOn $tprop SetColor 1 0 0 vtkActor2D textActor textActor VisibilityOff textActor SetMapper textMapper # Create the Renderer, RenderWindow, and RenderWindowInteractor # vtkInteractorStyleTrackballCamera style style AddObserver LeftButtonPressEvent {set MouseMotion 0; style OnLeftButtonDown} style AddObserver MouseMoveEvent {set MouseMotion 1; style OnMouseMove} style AddObserver LeftButtonReleaseEvent cbLBR vtkRenderer ren1 vtkRenderWindow renWin renWin AddRenderer ren1 vtkRenderWindowInteractor iren iren SetRenderWindow renWin iren SetInteractorStyle style iren SetPicker picker # Add the actors to the renderer, set the background and size # ren1 AddActor2D textActor ren1 AddActor sphereActor ren1 AddActor spikeActor ren1 SetBackground 1 1 1 renWin SetSize 300 300 # Get the camera and zoom in closer to the image. set cam1 [ren1 GetActiveCamera] $cam1 Zoom 1.4 # Set the user method (bound to key 'u') iren AddObserver UserEvent {wm deiconify .vtkInteract} iren Initialize # Withdraw the default tk window wm withdraw . # Create a Tcl procedure to create the text for the text mapper used to # display the results of picking. proc annotatePick {} { if { [picker GetCellId] < 0 } { textActor VisibilityOff } else { set selPt [picker GetSelectionPoint] set x [lindex $selPt 0] set y [lindex $selPt 1] set pickPos [picker GetPickPosition] set xp [lindex $pickPos 0] set yp [lindex $pickPos 1] set zp [lindex $pickPos 2] textMapper SetInput "($xp, $yp, $zp)" textActor SetPosition $x $y textActor VisibilityOn } renWin Render } proc cbLBR {} { global MouseMotion if {$MouseMotion == 0} { eval picker Pick [iren GetEventPosition] 0 ren1 } # Do the default things for the trackball style style OnLeftButtonUp } # Pick the cell at this location. picker Pick 85 126 0 ren1