1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
# This example shows how to use the InteractorStyleImage and add your own
# event handling. The InteractorStyleImage is a special interactor designed
# to be used with vtkImageActor in a rendering window context. It forces the
# camera to stay perpendicular to the x-y plane.
package require vtk
package require vtkinteraction
# Create the image
#
vtkPNGReader reader
reader SetDataSpacing 0.8 0.8 1.5
reader SetFileName "$VTK_DATA_ROOT/Data/fullhead15.png"
vtkImageShiftScale shiftScale
shiftScale SetInputConnection [reader GetOutputPort]
shiftScale SetShift 0
shiftScale SetScale 0.07
shiftScale SetOutputScalarTypeToUnsignedChar
vtkImageActor ia
[ia GetMapper] SetInputConnection [shiftScale GetOutputPort]
# Create the RenderWindow, Renderer and both Actors
vtkRenderer ren1
vtkRenderWindow renWin
renWin AddRenderer ren1
vtkRenderWindowInteractor iren
iren SetRenderWindow renWin
# Create an image interactor style and associate it with the
# interactive renderer. Then assign some callbacks with the
# appropriate events. THe callbacks are implemented as Tcl procs.
vtkInteractorStyleImage interactor
iren SetInteractorStyle interactor
interactor AddObserver LeftButtonPressEvent {StartZoom}
interactor AddObserver MouseMoveEvent {MouseMove}
interactor AddObserver LeftButtonReleaseEvent {EndZoom}
# Add the actors to the renderer, set the background and size
ren1 AddActor ia
ren1 SetBackground 0.1 0.2 0.4
renWin SetSize 400 400
# render the image
iren AddObserver UserEvent {wm deiconify .vtkInteract}
renWin Render
set cam1 [ren1 GetActiveCamera]
ren1 ResetCameraClippingRange
renWin Render
# prevent the tk window from showing up then start the event loop
wm withdraw .
### Supporting data for callbacks
vtkPoints pts
pts SetNumberOfPoints 4
vtkCellArray lines
lines InsertNextCell 5
lines InsertCellPoint 0
lines InsertCellPoint 1
lines InsertCellPoint 2
lines InsertCellPoint 3
lines InsertCellPoint 0
vtkPolyData pd
pd SetPoints pts
pd SetLines lines
vtkPolyDataMapper2D bboxMapper
bboxMapper SetInputData pd
vtkActor2D bboxActor
bboxActor SetMapper bboxMapper
[bboxActor GetProperty] SetColor 1 0 0
ren1 AddViewProp bboxActor
### Procedures for callbacks---------------------
set X 0
set Y 0
set bboxEnabled 0
proc StartZoom {} {
global X Y bboxEnabled
set xy [iren GetEventPosition]
set X [lindex $xy 0]
set Y [lindex $xy 1]
pts SetPoint 0 $X $Y 0
pts SetPoint 1 $X $Y 0
pts SetPoint 2 $X $Y 0
pts SetPoint 3 $X $Y 0
set bboxEnabled 1
bboxActor VisibilityOn
}
proc MouseMove {} {
global X Y bboxEnabled
if { $bboxEnabled } {
set xy [iren GetEventPosition]
set x [lindex $xy 0]
set y [lindex $xy 1]
pts SetPoint 1 $x $Y 0
pts SetPoint 2 $x $y 0
pts SetPoint 3 $X $y 0
renWin Render
}
}
#Do the hard stuff: pan and dolly
proc EndZoom {} {
global bboxEnabled
set p1 [pts GetPoint 0]
set p2 [pts GetPoint 2]
set x1 [lindex $p1 0]
set y1 [lindex $p1 1]
set x2 [lindex $p2 0]
set y2 [lindex $p2 1]
ren1 SetDisplayPoint $x1 $y1 0
ren1 DisplayToWorld
set p1 [ren1 GetWorldPoint]
ren1 SetDisplayPoint $x2 $y2 0
ren1 DisplayToWorld
set p2 [ren1 GetWorldPoint]
set p1X [lindex $p1 0]
set p1Y [lindex $p1 1]
set p1Z [lindex $p1 2]
set p2X [lindex $p2 0]
set p2Y [lindex $p2 1]
set p2Z [lindex $p2 2]
set camera [ren1 GetActiveCamera]
set focalPt [$camera GetFocalPoint]
set focalX [lindex $focalPt 0]
set focalY [lindex $focalPt 1]
set focalZ [lindex $focalPt 2]
set position [$camera GetPosition]
set positionX [lindex $position 0]
set positionY [lindex $position 1]
set positionZ [lindex $position 2]
set deltaX [expr $focalX - ($p1X + $p2X)/2.0]
set deltaY [expr $focalY - ($p1Y + $p2Y)/2.0]
#Set camera focal point to the center of the box
$camera SetFocalPoint [expr ($p1X + $p2X)/2.0] \
[expr ($p1Y + $p2Y)/2.0] $focalZ
$camera SetPosition [expr $positionX - $deltaX] \
[expr $positionY - $deltaY] $positionZ
#Now dolly the camera to fill the box
#This is a half-assed hack for demonstration purposes
if { $p1X > $p2X } {
set deltaX [expr $p1X - $p2X]
} else {
set deltaX [expr $p2X - $p1X]
}
if { $p1Y > $p2Y } {
set deltaY [expr $p1Y - $p2Y]
} else {
set deltaY [expr $p2Y - $p1Y]
}
set winSize [renWin GetSize]
set winX [lindex $winSize 0]
set winY [lindex $winSize 1]
set sx [expr $deltaX / $winX]
set sy [expr $deltaY / $winY]
if { $sx > $sy } {
set dolly [expr 1.0 + 1.0/(2.0*$sx)]
} else {
set dolly [expr 1.0 + 1.0/(2.0*$sy)]
}
$camera Dolly $dolly
ren1 ResetCameraClippingRange
set bboxEnabled 0
bboxActor VisibilityOff
renWin Render
}
iren Start
|