Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

373 lines
9.5 KiB

package require vtk
package require vtkinteraction
# This example demonstrates how to use the vtkImagePlaneWidget
# to probe a 3D image dataset with three orthogonal planes.
# Buttons are provided to:
# a) capture the render window display to a tiff file
# b) x,y,z buttons reset the widget to orthonormal
# positioning, set the horizontal slider to move the
# associated widget along its normal, and set the
# camera to face the widget
# c) right clicking on x,y,z buttons pops up a menu to set
# the associated widget's reslice interpolation mode
#
# Start by loading some data.
#
vtkVolume16Reader v16
v16 SetDataDimensions 64 64
v16 SetDataByteOrderToLittleEndian
v16 SetFilePrefix "$VTK_DATA_ROOT/Data/headsq/quarter"
v16 SetImageRange 1 93
v16 SetDataSpacing 3.2 3.2 1.5
v16 Update
scan [[v16 GetOutput] GetWholeExtent] "%d %d %d %d %d %d" \
xMin xMax yMin yMax zMin zMax
set spacing [[v16 GetOutput] GetSpacing]
set sx [lindex $spacing 0]
set sy [lindex $spacing 1]
set sz [lindex $spacing 2]
set origin [[v16 GetOutput] GetOrigin]
set ox [lindex $origin 0]
set oy [lindex $origin 1]
set oz [lindex $origin 2]
# An outline is shown for context.
#
vtkOutlineFilter outline
outline SetInputConnection [v16 GetOutputPort]
vtkPolyDataMapper outlineMapper
outlineMapper SetInputConnection [outline GetOutputPort]
vtkActor outlineActor
outlineActor SetMapper outlineMapper
# The shared picker enables us to use 3 planes at one time
# and gets the picking order right
#
vtkCellPicker picker
picker SetTolerance 0.005
# The 3 image plane widgets are used to probe the dataset.
#
vtkImagePlaneWidget planeWidgetX
planeWidgetX DisplayTextOn
planeWidgetX SetInput [v16 GetOutput]
planeWidgetX SetPlaneOrientationToXAxes
planeWidgetX SetSliceIndex 32
planeWidgetX SetPicker picker
planeWidgetX SetKeyPressActivationValue "x"
set prop1 [planeWidgetX GetPlaneProperty]
$prop1 SetColor 1 0 0
vtkImagePlaneWidget planeWidgetY
planeWidgetY DisplayTextOn
planeWidgetY SetInput [v16 GetOutput]
planeWidgetY SetPlaneOrientationToYAxes
planeWidgetY SetSliceIndex 32
planeWidgetY SetPicker picker
planeWidgetY SetKeyPressActivationValue "y"
set prop2 [planeWidgetY GetPlaneProperty]
$prop2 SetColor 1 1 0
planeWidgetY SetLookupTable [planeWidgetX GetLookupTable]
# for the z-slice, turn off texture interpolation:
# interpolation is now nearest neighbour, to demonstrate
# cross-hair cursor snapping to pixel centers
#
vtkImagePlaneWidget planeWidgetZ
planeWidgetZ DisplayTextOn
planeWidgetZ SetInput [v16 GetOutput]
planeWidgetZ SetPlaneOrientationToZAxes
planeWidgetZ SetSliceIndex 46
planeWidgetZ SetPicker picker
planeWidgetZ SetKeyPressActivationValue "z"
set prop3 [planeWidgetZ GetPlaneProperty]
$prop3 SetColor 0 0 1
planeWidgetZ SetLookupTable [planeWidgetX GetLookupTable]
set current_widget planeWidgetZ
set mode_widget planeWidgetZ
# Create the RenderWindow and Renderer
#
vtkRenderer ren1
vtkRenderWindow renWin
renWin AddRenderer ren1
# Add the outline actor to the renderer, set the background color and size
#
ren1 AddActor outlineActor
renWin SetSize 600 600
ren1 SetBackground 0.1 0.1 0.2
# Create the GUI
#
wm withdraw .
toplevel .top
wm title .top "vtkImagePlaneWidget Example"
wm protocol .top WM_DELETE_WINDOW ::vtk::cb_exit
set popm [menu .top.mm -tearoff 0]
set mode 1
$popm add radiobutton -label "nearest" -variable mode -value 0 \
-command SetInterpolation
$popm add radiobutton -label "linear" -variable mode -value 1 \
-command SetInterpolation
$popm add radiobutton -label "cubic" -variable mode -value 2 \
-command SetInterpolation
set display_frame [frame .top.f1]
set ctrl_buttons [frame .top.btns]
pack $display_frame $ctrl_buttons \
-side top -anchor n \
-fill both -expand f
set quit_button [button $ctrl_buttons.btn1 \
-text "Quit" \
-command ::vtk::cb_exit]
set capture_button [button $ctrl_buttons.btn2 \
-text "Tif" \
-command CaptureImage]
set x_button [button $ctrl_buttons.btn3 \
-text "x" \
-command AlignXaxis]
set y_button [button $ctrl_buttons.btn4 \
-text "y" \
-command AlignYaxis]
set z_button [button $ctrl_buttons.btn5 \
-text "z" \
-command AlignZaxis]
set last_btn -1
bind $x_button <Button-3> "set last_btn 0; configMenu; $popm post %X %Y"
bind $y_button <Button-3> "set last_btn 1; configMenu; $popm post %X %Y"
bind $z_button <Button-3> "set last_btn 2; configMenu; $popm post %X %Y"
# Share the popup menu among buttons, keeping
# track of associated widget's interpolation mode
#
proc configMenu { } {
global last_btn popm mode mode_widget
if { $last_btn == 0 } {
set mode_widget planeWidgetX
} elseif { $last_btn == 1 } {
set mode_widget planeWidgetY
} else {
set mode_widget planeWidgetZ
}
set mode [$mode_widget GetResliceInterpolate]
$popm entryconfigure $last_btn -variable mode
}
pack $quit_button $capture_button $x_button $y_button $z_button \
-side left \
-expand t -fill both
# Create the render widget
#
set renderer_frame [frame $display_frame.rFm]
pack $renderer_frame \
-padx 3 -pady 3 \
-side left -anchor n \
-fill both -expand f
set render_widget [vtkTkRenderWidget $renderer_frame.r \
-width 600 \
-height 600 \
-rw renWin]
pack $render_widget $display_frame \
-side top -anchor n \
-fill both -expand f
# Add a slice scale to browse the current slice stack
#
set slice_number [$current_widget GetSliceIndex]
scale .top.slice \
-from $zMin \
-to $zMax \
-orient horizontal \
-command SetSlice \
-variable slice_number \
-label "Slice"
pack .top.slice \
-fill x -expand f
proc SetSlice {slice} {
global current_widget
$current_widget SetSliceIndex $slice
ren1 ResetCameraClippingRange
renWin Render
}
::vtk::bind_tk_render_widget $render_widget
# Set the interactor for the widgets
#
set iact [[$render_widget GetRenderWindow] GetInteractor]
planeWidgetX SetInteractor $iact
planeWidgetX On
planeWidgetY SetInteractor $iact
planeWidgetY On
planeWidgetZ SetInteractor $iact
planeWidgetZ On
# Create an initial interesting view
#
set cam1 [ren1 GetActiveCamera]
$cam1 Elevation 110
$cam1 SetViewUp 0 0 -1
$cam1 Azimuth 45
ren1 ResetCameraClippingRange
# Render it
#
$render_widget Render
# Supporting procedures
#
# Align the camera so that it faces the desired widget
#
proc AlignCamera { } {
global ox oy oz sx sy sz xMax xMin yMax yMin zMax zMin slice_number
global current_widget
set cx [expr $ox + (0.5*($xMax - $xMin))*$sx]
set cy [expr $oy + (0.5*($yMax - $yMin))*$sy]
set cz [expr $oy + (0.5*($zMax - $zMin))*$sz]
set vx 0
set vy 0
set vz 0
set nx 0
set ny 0
set nz 0
set iaxis [$current_widget GetPlaneOrientation]
if { $iaxis == 0 } {
set vz -1
set nx [expr $ox + $xMax*$sx]
set cx [expr $ox + $slice_number*$sx]
} elseif { $iaxis == 1 } {
set vz -1
set ny [expr $oy + $yMax*$sy]
set cy [expr $oy + $slice_number*$sy]
} else {
set vy 1
set nz [expr $oz + $zMax*$sz]
set cz [expr $oz + $slice_number*$sz]
}
set px [expr $cx + $nx*2]
set py [expr $cy + $ny*2]
set pz [expr $cz + $nz*3]
set camera [ ren1 GetActiveCamera ]
$camera SetViewUp $vx $vy $vz
$camera SetFocalPoint $cx $cy $cz
$camera SetPosition $px $py $pz
$camera OrthogonalizeViewUp
ren1 ResetCameraClippingRange
renWin Render
}
# Capture the display and place in a tiff
#
proc CaptureImage { } {
vtkWindowToImageFilter w2i
vtkTIFFWriter writer
w2i SetInput renWin
w2i Update
writer SetInputConnection [w2i GetOutputPort]
writer SetFileName image.tif
renWin Render
writer Write
writer Delete
w2i Delete
}
# Align the widget back into orthonormal position,
# set the slider to reflect the widget's position,
# call AlignCamera to set the camera facing the widget
#
proc AlignXaxis { } {
global xMax xMin current_widget slice_number
set po [ planeWidgetX GetPlaneOrientation ]
if { $po == 3 } {
planeWidgetX SetPlaneOrientationToXAxes
set slice_number [expr ($xMax - $xMin)/2]
planeWidgetX SetSliceIndex $slice_number
} else {
set slice_number [planeWidgetX GetSliceIndex]
}
set current_widget planeWidgetX
.top.slice config -from $xMin -to $xMax
.top.slice set $slice_number
AlignCamera
}
proc AlignYaxis { } {
global yMin yMax current_widget slice_number
set po [ planeWidgetY GetPlaneOrientation ]
if { $po == 3 } {
planeWidgetY SetPlaneOrientationToYAxes
set slice_number [expr ($yMax - $yMin)/2]
planeWidgetY SetSliceIndex $slice_number
} else {
set slice_number [planeWidgetY GetSliceIndex]
}
set current_widget planeWidgetY
.top.slice config -from $yMin -to $yMax
.top.slice set $slice_number
AlignCamera
}
proc AlignZaxis { } {
global zMin zMax current_widget slice_number
set po [ planeWidgetZ GetPlaneOrientation ]
if { $po == 3 } {
planeWidgetZ SetPlaneOrientationToZAxes
set slice_number [expr ($zMax - $zMin)/2]
planeWidgetZ SetSliceIndex $slice_number
} else {
set slice_number [planeWidgetZ GetSliceIndex]
}
set current_widget planeWidgetZ
.top.slice config -from $zMin -to $zMax
.top.slice set $slice_number
AlignCamera
}
# Set the widget's reslice interpolation mode
# to the corresponding popup menu choice
#
proc SetInterpolation { } {
global mode_widget mode
if { $mode == 0 } {
$mode_widget TextureInterpolateOff
} else {
$mode_widget TextureInterpolateOn
}
$mode_widget SetResliceInterpolate $mode
renWin Render
}