]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/tcl/to_change/ev_userzoom.tcl
creaMaracasVisu Library
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / tcl / to_change / ev_userzoom.tcl
1 # ev_userzoom.tcl
2 # ====================================================================================================
3 # User interface events for a vtkTkRenderWidget widget. Based on TkInteractor.tcl
4 # ====================================================================================================
5 # Author  : Leonardo Florez-Valencia (lflorez@creatis.insa-lyon.fr)
6 # Created : 02/03/2001
7 # ====================================================================================================
8 # Log :
9 #       02/03/2001 ==> Initial implementation.
10 # ====================================================================================================
11
12 set gv_rendererFound 0;
13 set gv_deltaStep 0.001;
14 set gv_alfa 0.1;
15 set gv_actualPoint -1;
16
17 # -- PROCEDURE "bindBasicEvents { widget }" -----------------------------------------------------------
18 # -- Binds basic behavior the graphical VTK-widget.
19 # --
20 # -- IN  : widget = vtkTkRenderWidget
21 # -- OUT :
22 proc bindBasicEvents { widget } {
23
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 }
28
29 }; # proc bindBasicEvents { widget } {
30 # ----------------------------------------------------------------------------------------------------
31
32 # -- PROCEDURE "bindUserEvents { widget }" -----------------------------------------------------------
33 # -- Binds mouse and some keyboard interaction to the graphical VTK-widget.
34 # --
35 # -- Mouse motion :
36 # --                Left button + motion         = Rotates
37 # --                Middle button + motion or 
38 # --                Shift + Left button + motion = Side moves camera
39 # --                Right button + motion        = Moves
40 # --
41 # -- Keyboard :
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
52 # --
53 # -- IN  : widget = vtkTkRenderWidget
54 # -- OUT :
55 proc bindUserEvents { widget { rot 1 } } {
56
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 }
73
74 }; # proc bindUserEvents { widget } {
75 # ----------------------------------------------------------------------------------------------------
76
77 # -- PROCEDURE "bindZoomEvents { widget }" -----------------------------------------------------------
78 # -- Binds mouse and some keyboard interaction to the camera zoom on a VTK-widget.
79 # --
80 # -- Mouse motion :
81 # --                Left button + motion         = Rotates
82 # --                Middle button + motion or 
83 # --                Shift + Left button + motion = Pan
84 # --                Right button + motion        = Zoom
85 # --
86 # -- IN  : widget = vtkTkRenderWidget
87 # -- OUT :
88 proc bindZoomEvents { widget { rot 1 } } {
89
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 }
96
97 }; # proc bindZoomEvents { widget } {
98 # ----------------------------------------------------------------------------------------------------
99
100 proc updateRenderer { widget x y } {
101
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;
106
107         # Get the renderer window dimensions
108         set WindowX [ lindex [ $widget configure -width ] 4 ];
109         set WindowY [ lindex [ $widget configure -height ] 4 ];
110
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 ];
115
116         $renderers InitTraversal;
117         set gv_rendererFound 0;
118
119         for { set i 0 } { $i < $numRenderers } { incr i } {
120
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 ];
129
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 \
134                                                + $vpxmin ) ];
135                         set gv_windowCenterY [ expr double( $WindowY ) * ( ( $vpymax - $vpymin ) / 2.0 \
136                                                + $vpymin ) ];
137                         break;
138
139                 }; # fi
140
141         }; # rof
142
143         set gv_currentCamera [ $gv_currentRenderer GetActiveCamera ];
144         set lights [ $gv_currentRenderer GetLights ];
145         $lights InitTraversal;
146         set gv_currentLight [ $lights GetNextItem ];
147    
148         set gv_initX $x;
149         set gv_initY $y;
150         set gv_moving 0;
151
152 }; # proc updateRenderer { widget x y } {
153 # ----------------------------------------------------------------------------------------------------
154
155 proc render { } {
156
157         global gv_currentCamera gv_currentLight gv_currentRenderWindow;
158
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;
163
164 }; # proc render { } {
165 # ----------------------------------------------------------------------------------------------------
166
167 # -- PROCEDURE "setFollowPath { path } ---------------------------------------------------------------
168 # -- Sets a point set to interpolate a path for the camera.
169 #
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 } {
174
175         global gv_pointSet;
176         global gv_actualPoint;
177         
178         set gv_pointSet $path;
179         set gv_actualPoint 0;
180
181 }; # proc setFollowPath { path } {
182 # ----------------------------------------------------------------------------------------------------
183
184 proc unsetFollowPath { } {
185
186         set gv_actualPoint -1;
187
188 }; # proc unsetFollowPath { } {
189 # ----------------------------------------------------------------------------------------------------
190
191 proc ev_startMotion { widget x y } {
192
193         global gv_currentRenderWindow;
194         global gv_rendererFound;
195
196         updateRenderer $widget $x $y;
197         if { ! $gv_rendererFound } { return };
198         $gv_currentRenderWindow SetDesiredUpdateRate 1.0;
199
200 }; # proc evz_startMotion { widget x y } {
201 # ----------------------------------------------------------------------------------------------------
202
203 proc ev_endMotion { widget x y } {
204
205         global gv_currentRenderWindow;
206         global gv_rendererFound;
207
208         if { ! $gv_rendererFound } { return };
209         $gv_currentRenderWindow SetDesiredUpdateRate 0.01;
210         render;
211
212 }; # proc evz_endMotion { widget x y } {
213 # ----------------------------------------------------------------------------------------------------
214
215 proc evb_wireframe { widget } {
216
217         global gv_currentRenderer;
218
219         set actors [ $gv_currentRenderer GetActors ];
220         $actors InitTraversal;
221         set actor [ $actors GetNextItem ];
222
223         while { $actor != "" } {
224
225                 [ $actor GetProperty ] SetRepresentationToWireframe;
226                 set actor [ $actors GetNextItem ];
227
228         }; # fwhile
229
230         render;
231
232 }; # proc evb_wireframe { widget } {
233 # ----------------------------------------------------------------------------------------------------
234
235 proc evb_surface { widget } {
236
237         global gv_currentRenderer;
238
239         set actors [ $gv_currentRenderer GetActors ];
240         $actors InitTraversal;
241         set actor [ $actors GetNextItem ];
242
243         while { $actor != "" } {
244
245                 [ $actor GetProperty ] SetRepresentationToSurface;
246                 set actor [ $actors GetNextItem ];
247
248         }; #fwhile
249
250         render;
251
252 }; # proc evb_surface { widget } {
253 # ----------------------------------------------------------------------------------------------------
254
255 proc evb_enter { widget x y } {
256
257         #focus $widget;
258         #updateRenderer $widget $x $y;
259
260 }; # proc evb_enter { widget x y } {
261 # ----------------------------------------------------------------------------------------------------
262
263 proc evb_expose { widget } {
264
265    update;
266    [ $widget GetRenderWindow ] Render;
267
268 }; # proc evb_expose { widget } {
269 # ----------------------------------------------------------------------------------------------------
270
271 proc evu_rotate { widget x y } {
272
273         global gv_currentCamera;
274         global gv_initX gv_initY gv_deltaStep;
275         global gv_rendererFound;
276
277         if { ! $gv_rendererFound } { return };
278         
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 ];
285
286         # Yaw rotation
287         set yaw [ expr $yaw + fmod( $dx * $gv_deltaStep, 6.283185 ) ];
288         $gv_currentCamera Yaw $yaw;
289         
290         # Pitch rotation        
291         #set pitch [ expr $pitch + fmod( $dy * $gv_deltaStep, 6.283185 ) ];
292         #$gv_currentCamera Pitch $pitch;
293         #puts "$pitch";
294
295         render;
296
297 }; # 
298 # ----------------------------------------------------------------------------------------------------
299
300 proc evu_sideMove { widget x y } {
301 }; # 
302 # ----------------------------------------------------------------------------------------------------
303
304 proc evu_sideMove { widget x y } {
305 }; # 
306 # ----------------------------------------------------------------------------------------------------
307
308 proc evu_move { widget x y } {
309
310         global gv_currentCamera;
311         global gv_initX gv_initY;
312         global gv_deltaStep;
313         global gv_rendererFound;
314
315         if { ! $gv_rendererFound } { return };
316         
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 ];
321
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 ) ];
335         
336         $gv_currentCamera SetPosition $px $py $pz;
337         $gv_currentCamera SetFocalPoint $fx $fy $fz;
338         
339         render;
340
341 }; # proc evu_move { widget x y } {
342 # ----------------------------------------------------------------------------------------------------
343
344 proc evu_forward { widget } {
345 }; # 
346 # ----------------------------------------------------------------------------------------------------
347
348 proc evu_backward { widget } {
349 }; # 
350 # ----------------------------------------------------------------------------------------------------
351
352 proc evu_rotateLeft { widget } {
353 }; # 
354 # ----------------------------------------------------------------------------------------------------
355
356 proc evu_rotateRight { widget } {
357 }; # 
358 # ----------------------------------------------------------------------------------------------------
359
360 proc evu_rotateUp { widget } {
361 }; # 
362 # ----------------------------------------------------------------------------------------------------
363
364 proc evu_rotateDown { widget } {
365 }; # 
366 # ----------------------------------------------------------------------------------------------------
367
368 proc evu_sideMoveLeft { widget } {
369 }; # 
370 # ----------------------------------------------------------------------------------------------------
371
372 proc evu_sideMoveRight { widget } {
373 }; # 
374 # ----------------------------------------------------------------------------------------------------
375
376 proc evu_sideMoveUp { widget } {
377 }; # 
378 # ----------------------------------------------------------------------------------------------------
379
380 proc evu_sideMoveDown { widget } {
381 }; # 
382 # ----------------------------------------------------------------------------------------------------
383
384 proc evz_rotate { widget x y } {
385
386         global gv_currentCamera;
387         global gv_initX gv_initY;
388         global gv_rendererFound;
389
390         if { ! $gv_rendererFound } { return };
391
392         $gv_currentCamera Azimuth [ expr ( $gv_initX - $x ) ];
393         $gv_currentCamera Elevation [ expr ( $y - $gv_initY ) ];
394         $gv_currentCamera OrthogonalizeViewUp;
395
396         set gv_initX $x;
397         set gv_initY $y;
398
399         render;
400
401 }; # proc evz_rotate { widget x y } {
402 # ----------------------------------------------------------------------------------------------------
403
404 proc evz_pan { widget x y } {
405
406         global gv_currentRenderer gv_currentCamera;
407         global gv_windowCenterX gv_windowCenterY gv_initX gv_initY;
408         global gv_rendererFound;
409
410         if { ! $gv_rendererFound } { return };
411
412         set FPoint [ $gv_currentCamera GetFocalPoint ];
413         set FPoint0 [ lindex $FPoint 0 ];
414         set FPoint1 [ lindex $FPoint 1 ];
415         set FPoint2 [ lindex $FPoint 2 ];
416
417         set PPoint [ $gv_currentCamera GetPosition ];
418         set PPoint0 [ lindex $PPoint 0 ];
419         set PPoint1 [ lindex $PPoint 1 ];
420         set PPoint2 [ lindex $PPoint 2 ];
421
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 ];
426
427         set APoint0 [ expr $gv_windowCenterX + ( $x - $gv_initX ) ];
428         set APoint1 [ expr $gv_windowCenterY - ( $y - $gv_initY ) ];
429
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 ];
437
438         if { $RPoint3 != 0.0 } {
439
440                 set RPoint0 [ expr $RPoint0 / $RPoint3 ];
441                 set RPoint1 [ expr $RPoint1 / $RPoint3 ];
442                 set RPoint2 [ expr $RPoint2 / $RPoint3 ];
443
444         }; # fi
445
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 ];
450
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 ];
455
456         set gv_initX $x;
457         set gv_initY $y;
458
459         render;
460
461 }; # proc evz_pan { widget x y } {
462 # ----------------------------------------------------------------------------------------------------
463
464 proc evz_zoom { widget x y } {
465
466         global gv_currentCamera;
467         global gv_initX gv_initY;
468         global gv_rendererFound;
469
470         if { ! $gv_rendererFound } { return };
471
472         set zoomFactor [ expr pow( 1.02, ( 0.5 * ( $gv_initY - $y ) ) ) ];
473
474         if { [ $gv_currentCamera GetParallelProjection ] } {
475
476                 set parallelScale [ expr [ $gv_currentCamera GetParallelScale ] * $zoomFactor ];
477                 $gv_currentCamera SetParallelScale $parallelScale;
478
479         } else {
480
481                 $gv_currentCamera SetClippingRange \
482                                                    [ expr 0.1 / $zoomFactor ] \
483                                                    [ expr 1000 / $zoomFactor ];
484                 $gv_currentCamera Dolly $zoomFactor;
485
486         }; # fi
487
488         set gv_initX $x;
489         set gv_initY $y;
490
491         render;
492
493 }; # proc evz_zoom { widget x y } {
494 # ----------------------------------------------------------------------------------------------------
495
496 # EOF - ev_userzoom.tcl