2 # ====================================================================================================
3 # User interface events for a vtkTkRenderWidget widget. Based on TkInteractor.tcl
4 # ====================================================================================================
5 # Author : Leonardo Florez-Valencia (lflorez@creatis.insa-lyon.fr)
7 # ====================================================================================================
9 # 02/03/2001 ==> Initial implementation.
10 # ====================================================================================================
12 set gv_rendererFound 0;
13 set gv_deltaStep 0.001;
15 set gv_actualPoint -1;
17 # -- PROCEDURE "bindBasicEvents { widget }" -----------------------------------------------------------
18 # -- Binds basic behavior the graphical VTK-widget.
20 # -- IN : widget = vtkTkRenderWidget
22 proc bindBasicEvents { widget } {
24 bind $widget <w> { evb_wireframe %W }
25 bind $widget <s> { evb_surface %W }
26 bind $widget <Enter> { evb_enter %W %x %y }
27 bind $widget <Expose> { evb_expose %W }
29 }; # proc bindBasicEvents { widget } {
30 # ----------------------------------------------------------------------------------------------------
32 # -- PROCEDURE "bindUserEvents { widget }" -----------------------------------------------------------
33 # -- Binds mouse and some keyboard interaction to the graphical VTK-widget.
36 # -- Left button + motion = Rotates
37 # -- Middle button + motion or
38 # -- Shift + Left button + motion = Side moves camera
39 # -- Right button + motion = Moves
42 # -- UpArrow = Forward
43 # -- DownArrow = Backward
44 # -- LeftArrow = Rotate left
45 # -- RightArrow = Rotate right
46 # -- Shift + UpArrow = Rotate up
47 # -- Shift + DownArrow = Rotate down
48 # -- Shift + LeftArrow = Side move left
49 # -- Shift + RightArrow = Side move right
50 # -- Control + UpArrow = Side move up
51 # -- Control + DownArrow = Side move down
53 # -- IN : widget = vtkTkRenderWidget
55 proc bindUserEvents { widget { rot 1 } } {
57 bind $widget <Any-ButtonPress> { ev_startMotion %W %x %y}
58 bind $widget <Any-ButtonRelease> { ev_endMotion %W %x %y}
59 if { $rot == 1 } { bind $widget <B1-Motion> { evu_rotate %W %x %y } }
60 bind $widget <Shift-B1-Motion> { evu_sideMove %W %x %y }
61 bind $widget <B2-Motion> { evu_sideMove %W %x %y }
62 bind $widget <B3-Motion> { evu_move %W %x %y }
63 bind $widget <Up> { evu_forward %W }
64 bind $widget <Down> { evu_backward %W }
65 bind $widget <Left> { evu_rotateLeft %W }
66 bind $widget <Right> { evu_rotateRight %W }
67 bind $widget <Shift-Up> { evu_rotateUp %W }
68 bind $widget <Shift-Down> { evu_rotateDown %W }
69 bind $widget <Shift-Left> { evu_sideMoveLeft %W }
70 bind $widget <Shift-Right> { evu_sideMoveRight %W }
71 bind $widget <Control-Up> { evu_sideMoveUp %W }
72 bind $widget <Control-Down> { evu_sideMoveDown %W }
74 }; # proc bindUserEvents { widget } {
75 # ----------------------------------------------------------------------------------------------------
77 # -- PROCEDURE "bindZoomEvents { widget }" -----------------------------------------------------------
78 # -- Binds mouse and some keyboard interaction to the camera zoom on a VTK-widget.
81 # -- Left button + motion = Rotates
82 # -- Middle button + motion or
83 # -- Shift + Left button + motion = Pan
84 # -- Right button + motion = Zoom
86 # -- IN : widget = vtkTkRenderWidget
88 proc bindZoomEvents { widget { rot 1 } } {
90 bind $widget <Any-ButtonPress> { ev_startMotion %W %x %y}
91 bind $widget <Any-ButtonRelease> { ev_endMotion %W %x %y}
92 bind $widget <B1-Motion>
93 if { $rot == 1 } { bind $widget <B1-Motion> { evz_rotate %W %x %y } }
94 bind $widget <B2-Motion> { evz_pan %W %x %y }
95 bind $widget <B3-Motion> { evz_zoom %W %x %y }
97 }; # proc bindZoomEvents { widget } {
98 # ----------------------------------------------------------------------------------------------------
100 proc updateRenderer { widget x y } {
102 global gv_currentCamera gv_currentLight;
103 global gv_currentRenderWindow gv_currentRenderer;
104 global gv_rendererFound gv_initX gv_initY gv_moving;
105 global gv_windowCenterX gv_windowCenterY;
107 # Get the renderer window dimensions
108 set WindowX [ lindex [ $widget configure -width ] 4 ];
109 set WindowY [ lindex [ $widget configure -height ] 4 ];
111 # Find which renderer event has occurred in
112 set gv_currentRenderWindow [ $widget GetRenderWindow ];
113 set renderers [ $gv_currentRenderWindow GetRenderers ];
114 set numRenderers [ $renderers GetNumberOfItems ];
116 $renderers InitTraversal;
117 set gv_rendererFound 0;
119 for { set i 0 } { $i < $numRenderers } { incr i } {
121 set gv_currentRenderer [ $renderers GetNextItem ];
122 set vx [ expr double( $x ) / $WindowX ];
123 set vy [expr ( $WindowY - double( $y ) ) / $WindowY ];
124 set viewport [ $gv_currentRenderer GetViewport ];
125 set vpxmin [ lindex $viewport 0 ];
126 set vpymin [ lindex $viewport 1 ];
127 set vpxmax [ lindex $viewport 2 ];
128 set vpymax [ lindex $viewport 3 ];
130 if { $vx >= $vpxmin && $vx <= $vpxmax && \
131 $vy >= $vpymin && $vy <= $vpymax} {
132 set gv_rendererFound 1;
133 set gv_windowCenterX [ expr double( $WindowX ) * ( ( $vpxmax - $vpxmin ) / 2.0 \
135 set gv_windowCenterY [ expr double( $WindowY ) * ( ( $vpymax - $vpymin ) / 2.0 \
143 set gv_currentCamera [ $gv_currentRenderer GetActiveCamera ];
144 set lights [ $gv_currentRenderer GetLights ];
145 $lights InitTraversal;
146 set gv_currentLight [ $lights GetNextItem ];
152 }; # proc updateRenderer { widget x y } {
153 # ----------------------------------------------------------------------------------------------------
157 global gv_currentCamera gv_currentLight gv_currentRenderWindow;
159 eval $gv_currentLight SetPosition [ $gv_currentCamera GetPosition ];
160 eval $gv_currentLight SetFocalPoint [ $gv_currentCamera GetFocalPoint ];
161 $gv_currentCamera SetClippingRange 0.1 1000;
162 $gv_currentRenderWindow Render;
164 }; # proc render { } {
165 # ----------------------------------------------------------------------------------------------------
167 # -- PROCEDURE "setFollowPath { path } ---------------------------------------------------------------
168 # -- Sets a point set to interpolate a path for the camera.
170 # -- IN : A set of points that defines the path
171 # -- OUT : The user has been enabled to walk over the path, the normal view goes over
172 # -- the pendant direction.
173 proc setFollowPath { path } {
176 global gv_actualPoint;
178 set gv_pointSet $path;
179 set gv_actualPoint 0;
181 }; # proc setFollowPath { path } {
182 # ----------------------------------------------------------------------------------------------------
184 proc unsetFollowPath { } {
186 set gv_actualPoint -1;
188 }; # proc unsetFollowPath { } {
189 # ----------------------------------------------------------------------------------------------------
191 proc ev_startMotion { widget x y } {
193 global gv_currentRenderWindow;
194 global gv_rendererFound;
196 updateRenderer $widget $x $y;
197 if { ! $gv_rendererFound } { return };
198 $gv_currentRenderWindow SetDesiredUpdateRate 1.0;
200 }; # proc evz_startMotion { widget x y } {
201 # ----------------------------------------------------------------------------------------------------
203 proc ev_endMotion { widget x y } {
205 global gv_currentRenderWindow;
206 global gv_rendererFound;
208 if { ! $gv_rendererFound } { return };
209 $gv_currentRenderWindow SetDesiredUpdateRate 0.01;
212 }; # proc evz_endMotion { widget x y } {
213 # ----------------------------------------------------------------------------------------------------
215 proc evb_wireframe { widget } {
217 global gv_currentRenderer;
219 set actors [ $gv_currentRenderer GetActors ];
220 $actors InitTraversal;
221 set actor [ $actors GetNextItem ];
223 while { $actor != "" } {
225 [ $actor GetProperty ] SetRepresentationToWireframe;
226 set actor [ $actors GetNextItem ];
232 }; # proc evb_wireframe { widget } {
233 # ----------------------------------------------------------------------------------------------------
235 proc evb_surface { widget } {
237 global gv_currentRenderer;
239 set actors [ $gv_currentRenderer GetActors ];
240 $actors InitTraversal;
241 set actor [ $actors GetNextItem ];
243 while { $actor != "" } {
245 [ $actor GetProperty ] SetRepresentationToSurface;
246 set actor [ $actors GetNextItem ];
252 }; # proc evb_surface { widget } {
253 # ----------------------------------------------------------------------------------------------------
255 proc evb_enter { widget x y } {
258 #updateRenderer $widget $x $y;
260 }; # proc evb_enter { widget x y } {
261 # ----------------------------------------------------------------------------------------------------
263 proc evb_expose { widget } {
266 [ $widget GetRenderWindow ] Render;
268 }; # proc evb_expose { widget } {
269 # ----------------------------------------------------------------------------------------------------
271 proc evu_rotate { widget x y } {
273 global gv_currentCamera;
274 global gv_initX gv_initY gv_deltaStep;
275 global gv_rendererFound;
277 if { ! $gv_rendererFound } { return };
279 set dx [ expr $gv_initX - $x ];
280 set dy [ expr $gv_initY - $y ];
281 set ori [ $gv_currentCamera GetOrientation ];
282 set ori [ list 0 0 0 ];
283 set yaw [ lindex $ori 0 ];
284 set pitch [ lindex $ori 1 ];
287 set yaw [ expr $yaw + fmod( $dx * $gv_deltaStep, 6.283185 ) ];
288 $gv_currentCamera Yaw $yaw;
291 #set pitch [ expr $pitch + fmod( $dy * $gv_deltaStep, 6.283185 ) ];
292 #$gv_currentCamera Pitch $pitch;
298 # ----------------------------------------------------------------------------------------------------
300 proc evu_sideMove { widget x y } {
302 # ----------------------------------------------------------------------------------------------------
304 proc evu_sideMove { widget x y } {
306 # ----------------------------------------------------------------------------------------------------
308 proc evu_move { widget x y } {
310 global gv_currentCamera;
311 global gv_initX gv_initY;
313 global gv_rendererFound;
315 if { ! $gv_rendererFound } { return };
317 set dx [ expr $gv_initY - $y ];
318 set pos [ $gv_currentCamera GetPosition ];
319 set foc [ $gv_currentCamera GetFocalPoint ];
320 set nor [ $gv_currentCamera GetViewPlaneNormal ];
322 # Calculates the new position and focal point
323 set px [ expr [ lindex $pos 0 ] + ( [ lindex $nor 0 ] * $dx * 0.1 ) ];
324 set py [ expr [ lindex $pos 1 ] + ( [ lindex $nor 1 ] * $dx * 0.1 ) ];
325 set pz [ expr [ lindex $pos 2 ] + ( [ lindex $nor 2 ] * $dx * 0.1 ) ];
326 set fx [ expr [ lindex $foc 0 ] + ( [ lindex $nor 0 ] * $dx * 0.1 ) ];
327 set fy [ expr [ lindex $foc 1 ] + ( [ lindex $nor 1 ] * $dx * 0.1 ) ];
328 set fz [ expr [ lindex $foc 2 ] + ( [ lindex $nor 2 ] * $dx * 0.1 ) ];
329 # set px [ expr [ lindex $pos 0 ] + ( [ lindex $nor 0 ] * $dx * $gv_deltaStep ) ];
330 # set py [ expr [ lindex $pos 1 ] + ( [ lindex $nor 1 ] * $dx * $gv_deltaStep ) ];
331 # set pz [ expr [ lindex $pos 2 ] + ( [ lindex $nor 2 ] * $dx * $gv_deltaStep ) ];
332 # set fx [ expr [ lindex $foc 0 ] + ( [ lindex $nor 0 ] * $dx * $gv_deltaStep ) ];
333 # set fy [ expr [ lindex $foc 1 ] + ( [ lindex $nor 1 ] * $dx * $gv_deltaStep ) ];
334 # set fz [ expr [ lindex $foc 2 ] + ( [ lindex $nor 2 ] * $dx * $gv_deltaStep ) ];
336 $gv_currentCamera SetPosition $px $py $pz;
337 $gv_currentCamera SetFocalPoint $fx $fy $fz;
341 }; # proc evu_move { widget x y } {
342 # ----------------------------------------------------------------------------------------------------
344 proc evu_forward { widget } {
346 # ----------------------------------------------------------------------------------------------------
348 proc evu_backward { widget } {
350 # ----------------------------------------------------------------------------------------------------
352 proc evu_rotateLeft { widget } {
354 # ----------------------------------------------------------------------------------------------------
356 proc evu_rotateRight { widget } {
358 # ----------------------------------------------------------------------------------------------------
360 proc evu_rotateUp { widget } {
362 # ----------------------------------------------------------------------------------------------------
364 proc evu_rotateDown { widget } {
366 # ----------------------------------------------------------------------------------------------------
368 proc evu_sideMoveLeft { widget } {
370 # ----------------------------------------------------------------------------------------------------
372 proc evu_sideMoveRight { widget } {
374 # ----------------------------------------------------------------------------------------------------
376 proc evu_sideMoveUp { widget } {
378 # ----------------------------------------------------------------------------------------------------
380 proc evu_sideMoveDown { widget } {
382 # ----------------------------------------------------------------------------------------------------
384 proc evz_rotate { widget x y } {
386 global gv_currentCamera;
387 global gv_initX gv_initY;
388 global gv_rendererFound;
390 if { ! $gv_rendererFound } { return };
392 $gv_currentCamera Azimuth [ expr ( $gv_initX - $x ) ];
393 $gv_currentCamera Elevation [ expr ( $y - $gv_initY ) ];
394 $gv_currentCamera OrthogonalizeViewUp;
401 }; # proc evz_rotate { widget x y } {
402 # ----------------------------------------------------------------------------------------------------
404 proc evz_pan { widget x y } {
406 global gv_currentRenderer gv_currentCamera;
407 global gv_windowCenterX gv_windowCenterY gv_initX gv_initY;
408 global gv_rendererFound;
410 if { ! $gv_rendererFound } { return };
412 set FPoint [ $gv_currentCamera GetFocalPoint ];
413 set FPoint0 [ lindex $FPoint 0 ];
414 set FPoint1 [ lindex $FPoint 1 ];
415 set FPoint2 [ lindex $FPoint 2 ];
417 set PPoint [ $gv_currentCamera GetPosition ];
418 set PPoint0 [ lindex $PPoint 0 ];
419 set PPoint1 [ lindex $PPoint 1 ];
420 set PPoint2 [ lindex $PPoint 2 ];
422 $gv_currentRenderer SetWorldPoint $FPoint0 $FPoint1 $FPoint2 1.0;
423 $gv_currentRenderer WorldToDisplay;
424 set DPoint [ $gv_currentRenderer GetDisplayPoint ];
425 set focalDepth [ lindex $DPoint 2 ];
427 set APoint0 [ expr $gv_windowCenterX + ( $x - $gv_initX ) ];
428 set APoint1 [ expr $gv_windowCenterY - ( $y - $gv_initY ) ];
430 $gv_currentRenderer SetDisplayPoint $APoint0 $APoint1 $focalDepth;
431 $gv_currentRenderer DisplayToWorld;
432 set RPoint [ $gv_currentRenderer GetWorldPoint ];
433 set RPoint0 [ lindex $RPoint 0 ];
434 set RPoint1 [ lindex $RPoint 1 ];
435 set RPoint2 [ lindex $RPoint 2 ];
436 set RPoint3 [ lindex $RPoint 3 ];
438 if { $RPoint3 != 0.0 } {
440 set RPoint0 [ expr $RPoint0 / $RPoint3 ];
441 set RPoint1 [ expr $RPoint1 / $RPoint3 ];
442 set RPoint2 [ expr $RPoint2 / $RPoint3 ];
446 $gv_currentCamera SetFocalPoint \
447 [ expr ( $FPoint0 - $RPoint0 ) / 2.0 + $FPoint0 ] \
448 [ expr ( $FPoint1 - $RPoint1 ) / 2.0 + $FPoint1 ] \
449 [ expr ( $FPoint2 - $RPoint2 ) / 2.0 + $FPoint2 ];
451 $gv_currentCamera SetPosition \
452 [ expr ( $FPoint0 - $RPoint0 ) / 2.0 + $PPoint0 ] \
453 [ expr ( $FPoint1 - $RPoint1 ) / 2.0 + $PPoint1 ] \
454 [ expr ( $FPoint2 - $RPoint2 ) / 2.0 + $PPoint2 ];
461 }; # proc evz_pan { widget x y } {
462 # ----------------------------------------------------------------------------------------------------
464 proc evz_zoom { widget x y } {
466 global gv_currentCamera;
467 global gv_initX gv_initY;
468 global gv_rendererFound;
470 if { ! $gv_rendererFound } { return };
472 set zoomFactor [ expr pow( 1.02, ( 0.5 * ( $gv_initY - $y ) ) ) ];
474 if { [ $gv_currentCamera GetParallelProjection ] } {
476 set parallelScale [ expr [ $gv_currentCamera GetParallelScale ] * $zoomFactor ];
477 $gv_currentCamera SetParallelScale $parallelScale;
481 $gv_currentCamera SetClippingRange \
482 [ expr 0.1 / $zoomFactor ] \
483 [ expr 1000 / $zoomFactor ];
484 $gv_currentCamera Dolly $zoomFactor;
493 }; # proc evz_zoom { widget x y } {
494 # ----------------------------------------------------------------------------------------------------
496 # EOF - ev_userzoom.tcl