]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.cxx
Some indentation
[cpPlugins.git] / lib / cpPlugins / Extensions / Visualization / ImageInteractorStyle.cxx
1 #include <cpPlugins/Extensions/Visualization/ImageInteractorStyle.h>
2
3 #include <cmath>
4 #include <ctime>
5
6 #include <vtkAnnotatedCubeActor.h>
7 #include <vtkAxesActor.h>
8 #include <vtkCallbackCommand.h>
9 #include <vtkCamera.h>
10 #include <vtkCellArray.h>
11 #include <vtkCommand.h>
12 #include <vtkMatrix4x4.h>
13 #include <vtkPropAssembly.h>
14 #include <vtkProperty.h>
15 #include <vtkRendererCollection.h>
16 #include <vtkRenderWindow.h>
17 #include <vtkRenderWindowInteractor.h>
18
19 #include <cpPlugins/Extensions/Visualization/ImageSliceActors.h>
20 #include <cpPlugins/Extensions/Visualization/MPRActors.h>
21
22 // -------------------------------------------------------------------------
23 const int cpPlugins::Extensions::Visualization::
24 ImageInteractorStyle::CursorEvent = vtkCommand::UserEvent + 1;
25 const int cpPlugins::Extensions::Visualization::
26 ImageInteractorStyle::RadiusEvent = vtkCommand::UserEvent + 2;
27 const int cpPlugins::Extensions::Visualization::
28 ImageInteractorStyle::DoubleClickEvent = vtkCommand::UserEvent + 3;
29
30 // -------------------------------------------------------------------------
31 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
32 Self* cpPlugins::Extensions::Visualization::ImageInteractorStyle::
33 New( )
34 {
35   return( new Self( ) );
36 }
37
38 // -------------------------------------------------------------------------
39 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
40 Configure( ImageSliceActors* slice_actors, MPRActors* mpr_actors )
41 {
42   this->m_SliceActors = slice_actors;
43   this->m_MPRActors = mpr_actors;
44   this->SetModeToNavigation( );
45   this->PropPicker->AddPickList( slice_actors->GetImageActor( ) );
46   this->Modified( );
47 }
48
49 // -------------------------------------------------------------------------
50 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
51 AssociateInteractor( vtkRenderWindowInteractor* interactor )
52 {
53   if( interactor != NULL )
54   {
55     this->AssociatedInteractors.push_back( interactor );
56     this->Modified( );
57
58   } // fi
59 }
60
61 // -------------------------------------------------------------------------
62 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
63 SetModeToNavigation( )
64 {
65   this->Mode = Self::NavigationMode;
66 }
67
68 // -------------------------------------------------------------------------
69 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
70 SetModeToDeformation( )
71 {
72   this->Mode = Self::DeformationMode;
73 }
74
75 // -------------------------------------------------------------------------
76 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
77 SetInteractor( vtkRenderWindowInteractor* interactor, const int& axis )
78 {
79   this->Superclass::SetInteractor( interactor );
80   this->OrientationWidget->SetInteractor( interactor );
81   interactor->SetInteractorStyle( this );
82   if( interactor == NULL )
83     return;
84
85   // Get camera, avoiding segfaults
86   vtkRenderer* ren =
87     interactor->GetRenderWindow( )->GetRenderers( )->GetFirstRenderer( );
88   if( ren == NULL )
89     return;
90   vtkCamera* cam = ren->GetActiveCamera( );
91   if( cam == NULL )
92     return;
93
94   // Parallel projections are better when displaying 2D images
95   cam->ParallelProjectionOn( );
96   cam->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) );
97   if( axis == 0 )
98   {
99     cam->SetPosition( double( 1 ), double( 0 ), double( 0 ) );
100     cam->SetViewUp  ( double( 0 ), double( 1 ), double( 0 ) );
101   }
102   else if( axis == 1 )
103   {
104     cam->SetPosition( double( 0 ), double( 1 ), double(  0 ) );
105     cam->SetViewUp  ( double( 0 ), double( 0 ), double( -1 ) );
106   }
107   else // if( axis == 2 )
108   {
109     cam->SetPosition( double( 0 ), double( 0 ), double( 1 ) );
110     cam->SetViewUp  ( double( 0 ), double( 1 ), double( 0 ) );
111
112   } // fi
113   ren->ResetCamera( );
114
115   // Enable 2D orientation widget
116   this->OrientationWidget->SetEnabled( 1 );
117   this->OrientationWidget->InteractiveOff( );
118 }
119
120 // -------------------------------------------------------------------------
121 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
122 OnMouseMove( )
123 {
124   if( this->m_MPRActors == NULL )
125     return;
126   
127   if( this->CursorMoving )
128   {
129     bool picked = this->_PickPosition( this->Cursor );
130     if( picked )
131     {
132       for( int i = 0; i < 3; ++i )
133         if( this->m_SliceActors->GetAxis( ) != i )
134           this->m_MPRActors->SetSlice( i, this->Cursor[ i ] );
135       this->InvokeEvent( Self::CursorEvent, this->Cursor );
136       this->Interactor->Render( );
137       this->_RenderAssociateInteractors( );
138
139     } // fi
140   }
141   else if( this->RadiusMoving )
142   {
143     bool picked = this->_PickPosition( this->Radius );
144     if( picked )
145     {
146       this->InvokeEvent( Self::RadiusEvent, this->Radius );
147       this->_UpdateRadius( );
148
149     } // fi
150   }
151   else
152   {
153     switch( this->State )
154     {
155     case VTKIS_WINDOW_LEVEL:
156       this->WindowLevel( );
157       break;
158     case VTKIS_DOLLY:
159       this->Dolly( );
160       break;
161     case VTKIS_PAN:
162       this->Pan( );
163       break;
164     } // hctiws
165
166   } // fi
167 }
168
169 // -------------------------------------------------------------------------
170 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
171 OnLeftButtonDown( )
172 {
173   static double pnt[ 3 ];
174   static int pos[ 2 ];
175   this->Interactor->GetEventPosition( pos );
176   this->FindPokedRenderer( pos[ 0 ], pos[ 1 ] );
177   if( this->CurrentRenderer == NULL )
178     return;
179   this->GrabFocus( this->EventCallbackCommand );
180
181   // TODO: check this code
182   // Manage double-click
183   static const long epsilon_time = 800;
184   static long last_click_time = -( epsilon_time << 1 );
185   long click_time = static_cast< long >( std::clock( ) );
186   if( ( click_time - last_click_time ) < epsilon_time )
187   {
188     last_click_time = -( epsilon_time << 1 );
189     if( this->_PickPosition( pnt ) )
190       this->InvokeEvent( Self::DoubleClickEvent, pnt );
191   }
192   else
193   {
194     last_click_time = click_time;
195     if( this->Interactor->GetControlKey( ) )
196       this->StartCursorMoving( );
197
198   } // fi
199 }
200
201 // -------------------------------------------------------------------------
202 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
203 OnLeftButtonUp( )
204 {
205   if( this->CursorMoving )
206   {
207     this->EndCursorMoving( );
208     if( this->Interactor )
209       this->ReleaseFocus( );
210
211   } // fi
212 }
213
214 // -------------------------------------------------------------------------
215 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
216 OnMiddleButtonDown( )
217 {
218   int x = this->Interactor->GetEventPosition( )[ 0 ];
219   int y = this->Interactor->GetEventPosition( )[ 1 ];
220
221   this->FindPokedRenderer( x, y );
222   if( this->CurrentRenderer == NULL )
223     return;
224   this->GrabFocus( this->EventCallbackCommand );
225
226   if( this->Interactor->GetAltKey( ) )
227   {
228   }
229   else if( this->Interactor->GetControlKey( ) )
230   {
231     this->StartRadiusMoving( );
232   }
233   else if( this->Interactor->GetShiftKey( ) )
234   {
235   }
236   else
237     this->StartPan( );
238 }
239
240 // -------------------------------------------------------------------------
241 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
242 OnMiddleButtonUp( )
243 {
244   if( this->RadiusMoving )
245   {
246     this->EndRadiusMoving( );
247     if( this->Interactor )
248       this->ReleaseFocus( );
249   }
250   else
251   {
252     switch( this->State )
253     {
254     case VTKIS_PAN:
255       this->EndPan( );
256       break;
257     } // hctiws
258
259   } // fi
260 }
261
262 // -------------------------------------------------------------------------
263 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
264 OnRightButtonDown( )
265 {
266   int x = this->Interactor->GetEventPosition( )[ 0 ];
267   int y = this->Interactor->GetEventPosition( )[ 1 ];
268
269   this->FindPokedRenderer( x, y );
270   if( this->CurrentRenderer == NULL )
271     return;
272   this->GrabFocus( this->EventCallbackCommand );
273
274   if( this->Interactor->GetControlKey( ) )
275   {
276     this->WindowLevelStartPosition[ 0 ] = x;
277     this->WindowLevelStartPosition[ 1 ] = y;
278     this->StartWindowLevel( );
279   }
280   else
281   {
282     this->StartDolly( );
283   } // fi
284 }
285
286 // -------------------------------------------------------------------------
287 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
288 OnRightButtonUp( )
289 {
290   switch( this->State )
291   {
292   case VTKIS_WINDOW_LEVEL:
293   {
294     this->EndWindowLevel( );
295     if( this->Interactor )
296       this->ReleaseFocus( );
297   }
298   break;
299   case VTKIS_DOLLY:
300     this->EndDolly( );
301     break;
302   } // hctiws
303 }
304
305 // -------------------------------------------------------------------------
306 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
307 OnMouseWheelForward( )
308 {
309   if( this->m_SliceActors == NULL || this->Interactor == NULL )
310     return;
311   int off = 1;
312   if( this->Interactor->GetShiftKey( ) == 1 )
313     off *= 10;
314   int s = this->m_SliceActors->GetSliceNumber( ) + off;
315   int maxs = this->m_SliceActors->GetSliceNumberMaxValue( );
316   this->m_SliceActors->SetSliceNumber( ( s < maxs )? s: maxs );
317   this->Interactor->Render( );
318   this->_RenderAssociateInteractors( );
319 }
320
321 // -------------------------------------------------------------------------
322 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
323 OnMouseWheelBackward( )
324 {
325   if( this->m_SliceActors == NULL || this->Interactor == NULL )
326     return;
327   int off = 1;
328   if( this->Interactor->GetShiftKey( ) == 1 )
329     off *= 10;
330   int s = this->m_SliceActors->GetSliceNumber( ) - off;
331   int mins = this->m_SliceActors->GetSliceNumberMinValue( );
332   this->m_SliceActors->SetSliceNumber( ( mins < s )? s: mins );
333   this->Interactor->Render( );
334   this->_RenderAssociateInteractors( );
335 }
336
337 // -------------------------------------------------------------------------
338 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
339 OnChar( )
340 {
341   switch( this->Interactor->GetKeyCode( ) )
342   {
343   case 'r': case 'R':
344   {
345     vtkRenderer* ren =
346       this->Interactor->GetRenderWindow( )->
347       GetRenderers( )->GetFirstRenderer( );
348     if( ren != NULL )
349       ren->ResetCamera( );
350     this->Interactor->Render( );
351   }
352   break;
353   case 'w': case 'W': case 'l': case 'L':
354   {
355     if( this->m_MPRActors != NULL )
356     {
357       this->m_MPRActors->ResetWindowLevel( );
358       this->Interactor->Render( );
359       this->_RenderAssociateInteractors( );
360
361     } // fi
362   }
363   break;
364   } // hctiws
365 }
366
367 // -------------------------------------------------------------------------
368 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
369 WindowLevel( )
370 {
371   if( this->Mode == Self::NavigationMode )
372   {
373     if( this->Interactor == NULL )
374       return;
375     vtkRenderer* ren =
376       this->Interactor->GetRenderWindow( )->
377       GetRenderers( )->GetFirstRenderer( );
378     if( ren == NULL )
379       return;
380
381     // Compute scales
382     this->WindowLevelCurrentPosition[ 0 ] =
383       this->Interactor->GetEventPosition( )[ 0 ];
384     this->WindowLevelCurrentPosition[ 1 ] =
385       this->Interactor->GetEventPosition( )[ 1 ];
386     int* size = ren->GetSize( );
387     double sw = double(
388       this->WindowLevelCurrentPosition[ 0 ] -
389       this->WindowLevelStartPosition[ 0 ]
390       ) / double( size[ 0 ] );
391     double sl = (
392       this->WindowLevelStartPosition[ 1 ] -
393       this->WindowLevelCurrentPosition[ 1 ]
394       ) / double( size[ 1 ] );
395
396     double w = this->WindowLevelInitial[ 0 ] * ( double( 1 ) + sw );
397     double l = this->WindowLevelInitial[ 1 ] * ( double( 1 ) + sl );
398     double minw = this->m_MPRActors->GetMinWindow( );
399     double maxw = this->m_MPRActors->GetMaxWindow( );
400     double minl = this->m_MPRActors->GetMinLevel( );
401     double maxl = this->m_MPRActors->GetMaxLevel( );
402
403     if( w < minw ) w = minw;
404     if( maxw < w ) w = maxw;
405     if( l < minl ) l = minl;
406     if( maxl < l ) l = maxl;
407
408     this->m_MPRActors->SetWindowLevel( w, l );
409     this->Interactor->Render( );
410     this->_RenderAssociateInteractors( );
411   }
412   else if( this->Mode == Self::DeformationMode )
413   {
414     // TODO
415
416   } // fi
417 }
418
419 // -------------------------------------------------------------------------
420 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
421 StartWindowLevel( )
422 {
423   if( this->State != VTKIS_NONE )
424     return;
425   if( this->Mode == Self::NavigationMode )
426   {
427     this->StartState( VTKIS_WINDOW_LEVEL );
428
429     this->WindowLevelInitial[ 0 ] = this->m_MPRActors->GetWindow( );
430     this->WindowLevelInitial[ 1 ] = this->m_MPRActors->GetLevel( );
431   }
432   else if( this->Mode == Self::DeformationMode )
433   {
434     // TODO
435
436   } // fi
437 }
438
439 // -------------------------------------------------------------------------
440 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
441 EndWindowLevel( )
442 {
443   if( this->Mode == Self::NavigationMode )
444   {
445     if( this->State != VTKIS_WINDOW_LEVEL )
446       return;
447     this->StopState( );
448   }
449   else
450   {
451     // TODO
452
453   } // fi
454 }
455
456 // -------------------------------------------------------------------------
457 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
458 StartCursorMoving( )
459 {
460   if( this->CursorMoving )
461     return;
462   this->_PickPosition( this->Cursor );
463   this->CursorMoving = true;
464 }
465
466 // -------------------------------------------------------------------------
467 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
468 EndCursorMoving( )
469 {
470   if( !( this->CursorMoving ) )
471     return;
472   this->CursorMoving = false;
473 }
474
475 // -------------------------------------------------------------------------
476 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
477 StartRadiusMoving( )
478 {
479   if( this->RadiusMoving )
480     return;
481   this->_PickPosition( this->Radius );
482   this->RadiusMoving = true;
483   this->_UpdateRadius( );
484 }
485
486 // -------------------------------------------------------------------------
487 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
488 EndRadiusMoving( )
489 {
490   if( !( this->RadiusMoving ) )
491     return;
492   this->RadiusMoving = false;
493   this->_UpdateRadius( );
494   this->InvokeEvent( Self::RadiusEvent, NULL );
495 }
496
497 // -------------------------------------------------------------------------
498 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
499 ImageInteractorStyle( )
500   : Superclass( ),
501     Mode( Self::NavigationMode ),
502     m_SliceActors( NULL ),
503     m_MPRActors( NULL ),
504     CursorMoving( false ),
505     RadiusMoving( false )
506 {
507   // Orientation marks
508   vtkSmartPointer< vtkAnnotatedCubeActor > cube =
509     vtkSmartPointer< vtkAnnotatedCubeActor >::New( );
510   cube->GetCubeProperty( )->SetColor( 0.9, 0.7, 0.2 );
511   cube->GetTextEdgesProperty( )->SetLineWidth( 1 );
512   cube->GetTextEdgesProperty( )->SetDiffuse( 0 );
513   cube->GetTextEdgesProperty( )->SetAmbient( 1 );
514   cube->GetTextEdgesProperty( )->SetColor( 0.18, 0.28, 0.23 );
515   cube->GetXPlusFaceProperty( )->SetColor( 1, 0, 0 );
516   cube->GetXPlusFaceProperty( )->SetInterpolationToFlat( );
517   cube->GetXMinusFaceProperty( )->SetColor( 1, 0, 0 );
518   cube->GetXMinusFaceProperty( )->SetInterpolationToFlat( );
519   cube->GetYPlusFaceProperty( )->SetColor( 0, 1, 0 );
520   cube->GetYPlusFaceProperty( )->SetInterpolationToFlat( );
521   cube->GetYMinusFaceProperty( )->SetColor( 0, 1, 0 );
522   cube->GetYMinusFaceProperty( )->SetInterpolationToFlat( );
523   cube->GetZPlusFaceProperty( )->SetColor( 0, 0, 1 );
524   cube->GetZPlusFaceProperty( )->SetInterpolationToFlat( );
525   cube->GetZMinusFaceProperty( )->SetColor( 0, 0, 1 );
526   cube->GetZMinusFaceProperty( )->SetInterpolationToFlat( );
527
528   vtkSmartPointer< vtkAxesActor > axes =
529     vtkSmartPointer< vtkAxesActor >::New( );
530   axes->AxisLabelsOff( );
531   axes->SetShaftTypeToCylinder( );
532   axes->SetTotalLength( 2, 2, 2 );
533
534   vtkSmartPointer< vtkPropAssembly > actors =
535     vtkSmartPointer< vtkPropAssembly >::New( );
536   actors->AddPart( cube );
537   actors->AddPart( axes );
538
539   this->OrientationWidget =
540     vtkSmartPointer< vtkOrientationMarkerWidget >::New( );
541   this->OrientationWidget->SetOutlineColor( 0.93, 0.57, 0.13 );
542   this->OrientationWidget->SetOrientationMarker( actors );
543   this->OrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 );
544
545   // Circle
546   unsigned long circle_samples = 1000;
547   this->Circle = vtkSmartPointer< vtkPolyData >::New( );
548
549   vtkSmartPointer< vtkPoints > circle_points =
550     vtkSmartPointer< vtkPoints >::New( );
551   vtkSmartPointer< vtkCellArray > circle_lines =
552     vtkSmartPointer< vtkCellArray >::New( );
553   for( unsigned long s = 0; s < circle_samples; ++s )
554   {
555     double t = double( 6.2832 ) * double( s ) / double( circle_samples );
556     circle_points->InsertNextPoint(
557       std::cos( t ), std::sin( t ), double( 0 )
558       );
559
560     circle_lines->InsertNextCell( 2 );
561     circle_lines->InsertCellPoint( s );
562     circle_lines->InsertCellPoint( ( s + 1 ) % circle_samples );
563
564   } // rof
565   this->Circle->SetPoints( circle_points );
566   this->Circle->SetLines( circle_lines );
567
568   this->CircleMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
569   this->CircleMapper->SetInputData( this->Circle );
570   this->CircleActor = vtkSmartPointer< vtkActor >::New( );
571   this->CircleActor->SetMapper( this->CircleMapper );
572   this->CircleActor->GetProperty( )->SetColor( 1, 0, 1 );
573   this->CircleActor->GetProperty( )->SetLineWidth( 2 );
574
575   this->PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
576   this->PropPicker->PickFromListOn( );
577 }
578
579 // -------------------------------------------------------------------------
580 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
581 ~ImageInteractorStyle( )
582 {
583 }
584
585 // -------------------------------------------------------------------------
586 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
587 _RenderAssociateInteractors( )
588 {
589   std::vector< vtkRenderWindowInteractor* >::iterator rIt =
590     this->AssociatedInteractors.begin( );
591   for( ; rIt != this->AssociatedInteractors.end( ); ++rIt )
592     ( *rIt )->Render( );
593 }
594
595 // -------------------------------------------------------------------------
596 bool cpPlugins::Extensions::Visualization::ImageInteractorStyle::
597 _PickPosition( double pos[ 3 ] )
598 {
599   if( this->m_SliceActors == NULL )
600     return( false );
601
602   double x = double( this->Interactor->GetEventPosition( )[ 0 ] );
603   double y = double( this->Interactor->GetEventPosition( )[ 1 ] );
604   this->FindPokedRenderer( x, y );
605   int success =
606     this->PropPicker->Pick( x, y, double( 0 ), this->CurrentRenderer );
607   if( success == 0 )
608     return( false );
609   this->PropPicker->GetPickPosition( pos );
610
611   int axis = this->m_SliceActors->GetAxis( );
612   double* bounds = this->m_SliceActors->GetDisplayBounds( );
613   pos[ axis ] = bounds[ axis << 1 ];
614
615   return( true );
616 }
617
618 // -------------------------------------------------------------------------
619 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
620 _UpdateCursor( )
621 {
622   std::cout << "upcur" << std::endl;
623 }
624
625 // -------------------------------------------------------------------------
626 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
627 _UpdateRadius( )
628 {
629   vtkRenderer* ren =
630     this->Interactor->GetRenderWindow( )->
631     GetRenderers( )->GetFirstRenderer( );
632   if( ren == NULL )
633     return;
634   vtkCamera* cam = ren->GetActiveCamera( );
635   if( cam == NULL )
636     return;
637
638   if( this->RadiusMoving )
639   {
640     double x = this->Cursor[ 0 ] - this->Radius[ 0 ];
641     double y = this->Cursor[ 1 ] - this->Radius[ 1 ];
642     double z = this->Cursor[ 2 ] - this->Radius[ 2 ];
643     double r = std::sqrt( ( x * x ) + ( y * y ) + ( z * z ) );
644
645     vtkMatrix4x4* cam_matrix = cam->GetModelViewTransformMatrix( );
646     vtkSmartPointer< vtkMatrix4x4 > circle_matrix =
647       this->CircleActor->GetUserMatrix( );
648     if( circle_matrix.GetPointer( ) == NULL )
649     {
650       circle_matrix = vtkSmartPointer< vtkMatrix4x4 >::New( );
651       this->CircleActor->SetUserMatrix( circle_matrix );
652
653     } // fi
654     for( int i = 0; i < 4; ++i )
655     {
656       for( int j = 0; j < 4; ++j )
657       {
658         double v = cam_matrix->GetElement( i, j );
659         if( i < 3 && j == 3 )
660           v = this->Cursor[ i ];
661         if( i < 3 && j < 3 )
662           v *= r;
663         circle_matrix->SetElement( i, j, v );
664
665       } // rof
666
667     } // rof
668     this->CircleActor->Modified( );
669     ren->AddActor( this->CircleActor );
670   }
671   else
672     ren->RemoveActor( this->CircleActor );
673
674   this->Interactor->Render( );
675 }
676
677 // eof - $RCSfile$