Commit cf5d71cc authored by Sebastien Barre's avatar Sebastien Barre

ENH: change the way Tk bindings are set. Now compatible with the...

ENH: change the way Tk bindings are set. Now compatible with the RenderWindowInteractor and InteractorStyle framework.
parent d7159887
......@@ -21,9 +21,11 @@ package require vtkinteraction
# Next we create an instance of vtkSphereSource and set some of its
# properties
#
set sphere_max_res 60
set sphere_init_res 8
vtkSphereSource sphere
sphere SetThetaResolution 8
sphere SetPhiResolution 8
sphere SetThetaResolution $sphere_init_res
sphere SetPhiResolution $sphere_init_res
#
# We create an instance of vtkPolyDataMapper to map the polygonal data
......@@ -32,13 +34,12 @@ vtkSphereSource sphere
#
vtkPolyDataMapper sphereMapper
sphereMapper SetInput [sphere GetOutput]
#
# Create an actor to represent the sphere. The actor coordinates rendering of
# the graphics primitives for a mapper. We set this actor's mapper to be
# the mapper which we created above.
#
vtkActor sphereActor
vtkLODActor sphereActor
sphereActor SetMapper sphereMapper
#
......@@ -80,7 +81,7 @@ vtkPolyDataMapper spikeMapper
# the graphics primitives for a mapper. We set this actor's mapper to be
# the mapper which we created above.
#
vtkActor spikeActor
vtkLODActor spikeActor
spikeActor SetMapper spikeMapper
#
......@@ -117,15 +118,9 @@ set vtkw [vtkTkRenderWidget .ren \
-rw renWin]
#
# When using the vtkTkWidget classes you should not use the interactor
# classes such as vtkRenderWindowInteractor. While it may work, the
# behavior may be unstable. Normally you should use either an
# interactor (see Mace.Tcl) or a vtkTkWidget but never both for a
# given window. Hopefully, events can be bound on this widget just like any
# other Tk widget. BindTkRenderWidget sets events handlers that are similar
# to what we would achieve using vtkRenderWindowInteractor.
# Setup Tk bindings and VTK observers for that widget.
#
BindTkRenderWidget $vtkw
::vtk::bind_tk_render_widget $vtkw
#
# Once the VTK widget has been created it can be inserted into a whole Tk GUI
......@@ -137,7 +132,6 @@ BindTkRenderWidget $vtkw
#
# We first create a .params Tk frame into which we will pack all sliders.
#
frame .params
#
......@@ -152,7 +146,7 @@ frame .params
# corresponding VTK object.
#
set sth [scale .params.sth \
-from 3 -to 20 -res 1 \
-from 3 -to $sphere_max_res -res 1 \
-orient horizontal \
-label "Sphere Theta Resolution:" \
-command setSphereThetaResolution]
......@@ -181,7 +175,7 @@ proc setSphereThetaResolution {res} {
# resolution.
#
set sph [scale .params.sph \
-from 3 -to 20 -res 1 \
-from 3 -to $sphere_max_res -res 1 \
-orient horizontal \
-label "Sphere Phi Resolution:" \
-command setSpherePhiResolution]
......@@ -197,8 +191,9 @@ proc setSpherePhiResolution {res} {
# In the exact same way we create a scale slider controlling the cone
# resolution.
#
set cone_max_res $sphere_max_res
set cre [scale .params.cre \
-from 3 -to 20 -res 1 \
-from 3 -to $cone_max_res -res 1 \
-orient horizontal \
-label "Cone Source Resolution:" \
-command setConeSourceResolution]
......@@ -227,10 +222,9 @@ proc setGlyphScaleFactor {factor} {
}
#
# Let's add a quit button that will call the bye() (see below)
button .params.quit -text "Quit" -command bye
# Let's add a quit button that will trigger the exit callback (see below)
#
button .params.quit -text "Quit" -command ::vtk::cb_exit
#
# Finally we pack all sliders on top of each other (-side top) inside
......@@ -244,15 +238,11 @@ pack $vtkw .params -side top -fill both -expand yes
# We set the window manager (wm command) so that it registers a
# command to handle the WM_DELETE_WINDOW protocal request. This
# request is triggered when the widget is closed using the standard
# window manager icons or buttons. In this case the 'bye' procedure
# window manager icons or buttons. In this case the exit callback
# will be called and it will free up any objects we created then exit
# the application.
#
wm protocol . WM_DELETE_WINDOW bye
proc bye {} {
vtkCommand DeleteAllObjects
exit
}
wm protocol . WM_DELETE_WINDOW ::vtk::cb_exit
#
# You only need this line if you run this script from a Tcl shell
......
# First we include the VTK Tcl packages which will make available
# all of the vtk commands to Tcl
package require vtk
package require vtkinteraction
source HistogramWidget.tcl
# This script uses a vtkTkRenderWidget to create a
# Tk widget that is associated with a vtkRenderWindow.
#source TkInteractor.tcl
# Create the image reader
vtkImageReader reader
reader SetDataByteOrderToLittleEndian
reader SetDataExtent 0 63 0 63 1 93
reader SetFilePrefix "$VTK_DATA_ROOT/Data/headsq/quarter"
reader SetDataMask 0x7fff
reader SetDataByteOrderToLittleEndian
reader SetDataExtent 0 63 0 63 1 93
reader SetFilePrefix "$VTK_DATA_ROOT/Data/headsq/quarter"
reader SetDataMask 0x7fff
reader Update
scan [[reader GetOutput] GetWholeExtent] "%d %d %d %d %d %d" \
xMin xMax yMin yMax zMin zMax
# Magnify the image
set mag_factor 3
vtkImageMagnify magnify
magnify SetInput [reader GetOutput]
magnify SetMagnificationFactors $mag_factor $mag_factor 1
# Create the image viewer
# named viewer2 so regresion test will find the histogram window
vtkImageViewer viewer2
viewer2 SetInput [reader GetOutput]
viewer2 SetZSlice 14
viewer2 SetColorWindow 2000
viewer2 SetColorLevel 1000
viewer2 SetInput [magnify GetOutput]
viewer2 SetZSlice 14
viewer2 SetColorWindow 2000
viewer2 SetColorLevel 1000
# Create the GUI, i.e. two Tk image viewer, one for the image
# the other for the histogram, and a slice slider
# Create the GUI: two renderer widgets and a quit button
#
wm withdraw .
toplevel .top
# Set the window manager (wm command) so that it registers a
# command to handle the WM_DELETE_WINDOW protocal request. This
# request is triggered when the widget is closed using the standard
# window manager icons or buttons. In this case the exit callback
# will be called and it will free up any objects we created then exit
# the application.
wm protocol .top WM_DELETE_WINDOW ::vtk::cb_exit
# Create the vtkTkImageViewerWidget
frame .top.f1
vtkTkImageViewerWidget .top.f1.r1 -width 64 -height 64 -iv viewer2
set vtkiw [vtkTkImageViewerWidget .top.f1.r1 \
-width [expr ($xMax - $xMin + 1) * $mag_factor] \
-height [expr ($yMax - $yMin + 1) * $mag_factor] \
-iv viewer2]
# Setup some Tk bindings, a generic renwin interactor and VTK observers
# for that widget
::vtk::bind_tk_imageviewer_widget $vtkiw
# Create the histogram widget
source HistogramWidget.tcl
set hist [vtkHistogramWidget .top.f1.r2 512 192]
set slice_number [viewer2 GetZSlice]
set hist [vtkHistogramWidget .top.f1.r2]
HistogramWidgetSetInput $hist [reader GetOutput]
HistogramWidgetSetExtent $hist 0 63 0 63 14 14
HistogramWidgetSetExtent $hist $xMin $xMax $yMin $yMax $slice_number $slice_number
# let the regression test find the histogram window
set viewer [$hist GetImageViewer]
HistogramWidgetBind .top.f1.r2
# Add a 'Quit' button that will call the usual cb_exit callback and destroy
# all VTK objects
scan [[reader GetOutput] GetWholeExtent] "%d %d %d %d %d %d" \
xMin xMax yMin yMax zMin zMax
button .top.btn \
-text Quit \
-command ::vtk::cb_exit
# Add a slice scale to browse the whole stack
button .top.btn -text Quit -command exit
scale .top.slice -from $zMin -to $zMax -orient horizontal \
-command SetSlice -variable sliceNumber -label "Z Slice"
set sliceNumber 14
scale .top.slice \
-from $zMin \
-to $zMax \
-orient horizontal \
-command SetSlice \
-variable slice_number \
-label "Z Slice"
proc SetSlice {slice} {
global hist xMin xMax yMin yMax
global hist xMin xMax yMin yMax
viewer2 SetZSlice $slice
viewer2 Render
viewer2 SetZSlice $slice
viewer2 Render
HistogramWidgetSetExtent $hist $xMin $xMax $yMin $yMax $slice $slice
HistogramWidgetRender $hist
HistogramWidgetSetExtent $hist $xMin $xMax $yMin $yMax $slice $slice
HistogramWidgetRender $hist
}
pack .top.f1.r1 -side left -padx 3 -pady 3 -fill both -expand f
pack $hist -side left -padx 3 -pady 3 -fill both -expand t
pack .top.f1 -fill both -expand t
pack .top.slice .top.btn -fill x -expand f
# Pack all gui elements
pack $vtkiw \
-side left -anchor n \
-padx 3 -pady 3 \
-fill x -expand f
BindTkImageViewer .top.f1.r1
HistogramWidgetBind .top.f1.r2
pack $hist \
-side left \
-padx 3 -pady 3 \
-fill both -expand t
pack .top.f1 \
-fill both -expand t
pack .top.slice .top.btn \
-fill x -expand f
# You only need this line if you run this script from a Tcl shell
# (tclsh) instead of a Tk shell (wish)
tkwait window .
......@@ -95,12 +95,12 @@ frame .top.f2
pack .top.f1 .top.f2 -side top -expand 1 -fill both
vtkTkRenderWidget .top.f1.rw -width 400 -height 400 -rw rw
BindTkRenderWidget .top.f1.rw
::vtk::bind_tk_render_widget .top.f1.rw
pack .top.f1.rw -expand 1 -fill both
button .top.f2.b0 -text "Print" -command {PrintWithMesa}
button .top.f2.b1 -text "Quit" -command {vtkCommand DeleteAllObjects; exit}
button .top.f2.b1 -text "Quit" -command ::vtk::cb_exit
pack .top.f2.b0 -expand 1 -fill x
pack .top.f2.b1 -expand 1 -fill x
......
......@@ -15,7 +15,7 @@ pack .top.f1 .top.f2 -side top -expand 1 -fill both
vtkRenderWindow renWin
vtkTkRenderWidget .top.f1.rw -width 400 -height 400 -rw renWin
BindTkRenderWidget .top.f1.rw
::vtk::bind_tk_render_widget .top.f1.rw
pack .top.f1.rw -expand 1 -fill both
# create a rendering window and renderer
......@@ -39,8 +39,6 @@ proc ToggleGhostCells {} {
renWin Render
}
proc test {slab} {
for { set i 0} {$i <= 100} {set i [expr $i + 5]} {
puzzle MoveVertical $slab $i 1
......@@ -48,7 +46,6 @@ proc test {slab} {
}
}
vtkSpherePuzzle puzzle
vtkPolyDataMapper mapper
mapper SetInput [puzzle GetOutput]
......@@ -61,9 +58,6 @@ vtkPolyDataMapper mapper2
vtkActor actor2
actor2 SetMapper mapper2
# Add the actors to the renderer, set the background and size
#
ren1 AddActor actor
......@@ -71,7 +65,6 @@ ren1 AddActor actor2
ren1 SetBackground 0.1 0.2 0.4
bind .top.f1.rw <Motion> {MotionCallback %x %y}
bind .top.f1.rw <KeyPress-m> {ButtonCallback %x %y}
......
......@@ -144,10 +144,9 @@ set vtkw [vtkTkRenderWidget .ren \
pack $vtkw -side top -fill both -expand yes
#
# BindTkRenderWidget sets events handlers that are similar
# to what we would achieve using vtkRenderWindowInteractor.
# Sets event handlers
#
BindTkRenderWidget $vtkw
::vtk::bind_tk_render_widget $vtkw
#
# Create a menubar.
......@@ -162,12 +161,7 @@ set file_menu [menu $menubar.file]
$file_menu add command \
-label "Quit" \
-command bye
proc bye {} {
vtkCommand DeleteAllObjects
exit
}
-command ::vtk::cb_exit
$menubar add cascade -label "File" -menu $file_menu
......@@ -449,11 +443,10 @@ pack $gui -side top -anchor s -fill x -expand yes
# command to handle the WM_DELETE_WINDOW protocal request..
#
wm title . "Texture mapper/transform demo"
wm protocol . WM_DELETE_WINDOW bye
wm protocol . WM_DELETE_WINDOW ::vtk::cb_exit
#
# You only need this line if you run this script from a Tcl shell
# (tclsh) instead of a Tk shell (wish)
#
tkwait window .
......@@ -9,12 +9,16 @@
package require vtk
package require vtkinteraction
#
# Create an SLC reader and read in the data.
#
vtkSLCReader reader
reader SetFileName "$VTK_DATA_ROOT/Data/neghip.slc"
#
# Create transfer functions for opacity and color to be used in volume
# properties.
#
vtkPiecewiseFunction opacityTransferFunction
opacityTransferFunction AddPoint 20 0.0
opacityTransferFunction AddPoint 255 0.2
......@@ -26,7 +30,9 @@ vtkColorTransferFunction colorTransferFunction
colorTransferFunction AddRGBPoint 192.0 0.0 1.0 0.0
colorTransferFunction AddRGBPoint 255.0 0.0 0.2 0.0
#
# Create volume properties
#
vtkVolumeProperty volumeProperty
volumeProperty SetColor colorTransferFunction
volumeProperty SetScalarOpacity opacityTransferFunction
......@@ -37,15 +43,19 @@ vtkVolumeProperty volumeProperty2
volumeProperty2 SetScalarOpacity opacityTransferFunction
volumeProperty2 SetInterpolationTypeToLinear
#
# Create a volume ray cast mapper. The volume is used for levels 1 and 2 of
# LODProp3D.
#
vtkVolumeRayCastCompositeFunction compositeFunction
vtkVolumeRayCastMapper volumeMapper
volumeMapper SetInput [reader GetOutput]
volumeMapper SetVolumeRayCastFunction compositeFunction
#
# Set up the color lookup table for the probe planes to be used in levels 3 and
# 4 of the LODProp3D
#
vtkLookupTable ColorLookupTable
ColorLookupTable SetNumberOfTableValues 256
......@@ -59,8 +69,10 @@ for { set i 0 } { $i < 256 } { incr i } {
ColorLookupTable SetTableValue $i $r $g $b $a
}
#
# Create planes or different resolutions to probe the data read in using the
# SLC reader. The probe results are used as levels 3 and 4 of the LODProp3D.
#
set types [list hres lres]
foreach type $types {
for { set i 0 } { $i < 3 } { incr i } {
......@@ -108,7 +120,9 @@ foreach type $types {
probeMapper_${type} SetScalarRange 0 255
}
#
# Set the resolution of each of the planes just created
#
plane0_hres SetResolution 60 60
plane1_hres SetResolution 60 60
plane2_hres SetResolution 60 60
......@@ -116,11 +130,15 @@ plane0_lres SetResolution 25 25
plane1_lres SetResolution 25 25
plane2_lres SetResolution 25 25
#
# Set the opacity to be used in the probe mappers
#
vtkProperty probeProperty
probeProperty SetOpacity 0.99
#
# Create outline to be used as level 5 in the LODProp3D
#
vtkOutlineFilter outline
outline SetInput [reader GetOutput]
......@@ -130,7 +148,9 @@ vtkPolyDataMapper outlineMapper
vtkProperty outlineProperty
outlineProperty SetColor 1 1 1
#
# Create the LODProp3D and add the mappers to it.
#
vtkLODProp3D lod
set level1 [lod AddLOD volumeMapper volumeProperty2 0.0]
set level2 [lod AddLOD volumeMapper volumeProperty 0.0]
......@@ -138,9 +158,139 @@ set level3 [lod AddLOD probeMapper_hres probeProperty 0.0]
set level4 [lod AddLOD probeMapper_lres probeProperty 0.0]
set level5 [lod AddLOD outlineMapper outlineProperty 0.0]
#
# Create the render window and the renderer.
#
vtkRenderWindow renWin
vtkRenderer ren1
renWin AddRenderer ren1
#
# Add the LODProp3D to the renderer and set the background
#
ren1 AddProp lod
ren1 SetBackground 0.1 0.2 0.4
#
# Withdraw the default tk window
#
wm withdraw .
#
# Create the user interface including the RenderWindow
#
toplevel .top \
-visual best
wm protocol .top WM_DELETE_WINDOW ::vtk::cb_exit
frame .top.ren
frame .top.controls
pack .top.controls \
-side left -anchor n \
-padx 3 -pady 3
pack .top.ren \
-side right -anchor n \
-padx 3 -pady 3 \
-expand t -fill both
#
# Create Tk renderwidget, bind events
#
vtkTkRenderWidget .top.ren.rw \
-rw renWin \
-width 300 \
-height 300
::vtk::bind_tk_render_widget .top.ren.rw
pack .top.ren.rw \
-expand t -fill both
#
# Create LOD display controls
#
label .top.controls.lod \
-text "LOD Selected:"
pack .top.controls.lod \
-side top -anchor w \
-padx 5 -pady 6
label .top.controls.l1 -text "Level 1 FPS:"
label .top.controls.l2 -text "Level 2 FPS:"
label .top.controls.l3 -text "Level 3 FPS:"
label .top.controls.l4 -text "Level 4 FPS:"
label .top.controls.l5 -text "Level 5 FPS:"
pack .top.controls.l1 .top.controls.l2 .top.controls.l3 .top.controls.l4 .top.controls.l5 \
-side top -anchor w \
-padx 5 -pady 2
#
# Create frame rate controls
#
set still_update_rate 0.5
set interactive_update_rate 5.0
proc update_rates {{foo 0}} {
global still_update_rate interactive_update_rate
set iren [renWin GetInteractor]
$iren SetStillUpdateRate $still_update_rate
$iren SetDesiredUpdateRate $interactive_update_rate
}
update_rates
scale .top.controls.s1 \
-label "Still FPS:" \
-orient horizontal \
-length 150 \
-from 0.05 -to 1.0 -resolution 0.05 \
-variable still_update_rate \
-command update_rates \
-highlightthickness 0
scale .top.controls.s2 \
-label "Moving FPS:" \
-orient horizontal \
-length 150 \
-from 1.0 -to 100.0 -resolution 1.0 \
-variable interactive_update_rate \
-command update_rates \
-highlightthickness 0
pack .top.controls.s1 .top.controls.s2 \
-side top \
-anchor w -padx 5 -pady 6
button .top.controls.quit \
-text "Quit" \
-command ::vtk::cb_exit
pack .top.controls.quit \
-side top \
-padx 5 -pady 6 \
-expand 1 -fill both
#
# Determine whether to allow automatic LOD selection.
#
if { [info command rtExMath] != "" } {
lod AutomaticLODSelectionOff
lod SetSelectedLODID $level3
}
#
# Create a Tcl procedure to display (in the user interface) which LOD is
# currently active.
# This proc is called each time an EndEvent is triggered by the renderer.
#
renWin AddObserver EndEvent ChangeLabels
proc ChangeLabels { } {
global level1 level2 level3 level4 level5
set value [lod GetLastRenderedLODID]
......@@ -195,88 +345,12 @@ proc ChangeLabels { } {
.top.controls.l5 configure -text \
"Level 5 FPS: [format "%.2f" [expr 1.0 / $value]]"
}
update
}
# Set the ChangeLabels proc to be executed when rendering is finished
set TkInteractor_EndRenderMethod ChangeLabels
# Withdraw the default tk window
wm withdraw .
# Create the user interface including the RenderWindow
toplevel .top -visual best
frame .top.ren
frame .top.controls
pack .top.controls .top.ren -side left -padx 10 -pady 10
vtkRenderWindow renWin
vtkTkRenderWidget .top.ren.rw -rw renWin -width 256 -height 256
BindTkRenderWidget .top.ren.rw
pack .top.ren.rw
label .top.controls.lod -text "LOD Selected:"
pack .top.controls.lod -side top -anchor w -padx 5 -pady 6
label .top.controls.l1 -text "Level 1 FPS:"
pack .top.controls.l1 -side top -anchor w -padx 5 -pady 2
label .top.controls.l2 -text "Level 2 FPS:"
pack .top.controls.l2 -side top -anchor w -padx 5 -pady 2
label .top.controls.l3 -text "Level 3 FPS:"
pack .top.controls.l3 -side top -anchor w -padx 5 -pady 2
label .top.controls.l4 -text "Level 4 FPS:"
pack .top.controls.l4 -side top -anchor w -padx 5 -pady 2
label .top.controls.l5 -text "Level 5 FPS:"
pack .top.controls.l5 -side top -anchor w -padx 5 -pady 2
set TkInteractor_StillUpdateRate 0.5
set TkInteractor_InteractiveUpdateRate 5.0
scale .top.controls.s1 -label "Still FPS:" -orient horizontal \
-length 150 -from 0.05 -to 1.0 -resolution 0.05 \
-variable TkInteractor_StillUpdateRate -highlightthickness 0
pack .top.controls.s1 -side top -anchor w -padx 5 -pady 6
scale .top.controls.s2 -label "Moving FPS:" -orient horizontal \
-length 150 -from 1.0 -to 30.0 -resolution 1.0 \
-variable TkInteractor_InteractiveUpdateRate -highlightthickness 0
pack .top.controls.s2 -side top -anchor w -padx 5 -pady 6
button .top.controls.quit -text "Quit" -command {exit}
pack .top.controls.quit -side top -padx 5 -pady 6 -expand 1 -fill both
# Create the renderer.
vtkRenderer ren1
renWin AddRenderer ren1
# Add the LODProp3D to the renderer and set the background
ren1 AddProp lod
ren1 SetBackground 0.1 0.2 0.4
# Create a Tcl procedure to check whether to abort rendering
proc TkCheckAbort {} {
set foo [renWin GetEventPending]
if {$foo != 0} {renWin SetAbortRender 1}
}
renWin AddObserver AbortCheckEvent {TkCheckAbort}
#
# Render into the RenderWindow
#
renWin Render
# Determine whether to allow automatic LOD selection.
if { [info command rtExMath] != "" } {
lod AutomaticLODSelectionOff
lod SetSelectedLODID $level3
}
tkwait window .
# Update the renderer and render
UpdateRenderer .top.ren.rw 0 0
Render .top.ren.rw
......@@ -3,12 +3,12 @@ package require vtkinteraction
set root [toplevel .top -visual {truecolor 24}]
wm title .top "superquadric viewer"
wm protocol .top WM_DELETE_WINDOW exit
wm protocol .top WM_DELETE_WINDOW ::vtk::cb_exit
# create render window
vtkRenderWindow renWin
set ren [vtkTkRenderWidget $root.ren -width 550 -height 450 -rw renWin]
BindTkRenderWidget $ren
::vtk::bind_tk_render_widget $ren
# create parameter sliders
set prs [scale $root.prs -from 0 -to 3.5 -res 0.1 -orient horizontal \
......
This diff is collapsed.
......@@ -48,10 +48,10 @@ Example: see Examples/GUI/Tcl/Mace.Tcl.
ii) 'vtkTkRenderWidget bindings':
The vtkinteraction package also brings a set of user-interaction bindings for the vtkTkRenderWidget class. It allows you to use this Tk widget in a way similar to the usual VTK interactor. Once the package is loaded, call BindTkRenderWidget to associate the bindings to the render widget:
The vtkinteraction package also brings a set of user-interaction bindings for the vtkTkRenderWidget class. It allows you to use this Tk widget in a way similar to the usual VTK interactor. Once the package is loaded, call ::vtk::bind_tk_render_widget to associate the bindings to the render widget:
set ren [vtkTkRenderWidget .ren -width 300 -height 300 -rw renWin]
BindTkRenderWidget $ren
::vtk::bind_tk_render_widget $ren
Example: see Examples/GUI/Tcl/MaceTk.Tcl.
......
package provide vtkinteraction 4.0
proc BindTkImageViewer {widget} {
# to avoid queing up multple expose events.
SetWidgetVariableValue $widget Rendering 0
set imager [[$widget GetImageViewer] GetRenderer]