]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Visualization/ImageSliceActors.cxx
Widget integration (step 5/6): generic widget controller finished and tested on linux...
[cpPlugins.git] / lib / cpExtensions / Visualization / ImageSliceActors.cxx
1 #include <cpExtensions/Visualization/ImageSliceActors.h>
2
3 #include <sstream>
4
5 #include <vtkAlgorithmOutput.h>
6 #include <vtkCellArray.h>
7 #include <vtkImageData.h>
8 #include <vtkInformation.h>
9 #include <vtkPlane.h>
10 #include <vtkPoints.h>
11 #include <vtkProperty.h>
12 #include <vtkRenderer.h>
13 #include <vtkStreamingDemandDrivenPipeline.h>
14 #include <vtkTextProperty.h>
15
16 // -------------------------------------------------------------------------
17 cpExtensions::Visualization::ImageSliceActors*
18 cpExtensions::Visualization::ImageSliceActors::
19 New( )
20 {
21   return( new Self( ) );
22 }
23
24 // -------------------------------------------------------------------------
25 void cpExtensions::Visualization::ImageSliceActors::
26 AddInputConnection( vtkAlgorithmOutput* aout, int axis )
27 {
28   vtkSmartPointer< vtkImageSliceMapper > mapper =
29     vtkSmartPointer< vtkImageSliceMapper >::New( );
30   this->SliceMappers.push_back( mapper );
31   mapper->SetInputConnection( aout );
32   this->_ConfigureNewInput( axis );
33 }
34
35 // -------------------------------------------------------------------------
36 void cpExtensions::Visualization::ImageSliceActors::
37 AddInputData( vtkImageData* data, int axis )
38 {
39   vtkSmartPointer< vtkImageSliceMapper > mapper =
40     vtkSmartPointer< vtkImageSliceMapper >::New( );
41   this->SliceMappers.push_back( mapper );
42   mapper->SetInputData( data );
43   this->_ConfigureNewInput( axis );
44 }
45
46 // -------------------------------------------------------------------------
47 void cpExtensions::Visualization::ImageSliceActors::
48 Clear( )
49 {
50   // Unbind from container
51   this->RemoveAllItems( );
52
53   // Delete all images
54   this->SliceMappers.clear( );
55   this->ImageActors.clear( );
56   this->AssociatedActors.clear( );
57
58   // Reconfigure unique objects
59   this->PlaneFunction = vtkSmartPointer< vtkPlane >::New( );
60   this->PlaneSource   = vtkSmartPointer< vtkPolyData >::New( );
61   this->PlaneMapper   = vtkSmartPointer< vtkPolyDataMapper >::New( );
62   this->TextActor     = vtkSmartPointer< vtkTextActor >::New( );
63   this->PlaneActor    = vtkSmartPointer< vtkActor >::New( );
64   this->TextBuffer[ 0 ] = '\0';
65
66   // Unique objects configuration
67   vtkSmartPointer< vtkPoints > plane_points =
68     vtkSmartPointer< vtkPoints >::New( );
69   vtkSmartPointer< vtkCellArray > plane_lines =
70     vtkSmartPointer< vtkCellArray >::New( );
71
72   plane_points->InsertNextPoint( 0, 0, 0 );
73   plane_points->InsertNextPoint( 0, 1, 0 );
74   plane_points->InsertNextPoint( 1, 1, 0 );
75   plane_points->InsertNextPoint( 1, 0, 0 );
76   plane_lines->InsertNextCell( 5 );
77   plane_lines->InsertCellPoint( 0 );
78   plane_lines->InsertCellPoint( 1 );
79   plane_lines->InsertCellPoint( 2 );
80   plane_lines->InsertCellPoint( 3 );
81   plane_lines->InsertCellPoint( 0 );
82   this->PlaneSource->SetPoints( plane_points );
83   this->PlaneSource->SetLines( plane_lines );
84
85   this->PlaneMapper->SetInputData( this->PlaneSource );
86   this->PlaneActor->SetMapper( this->PlaneMapper );
87
88   this->TextActor->SetTextScaleModeToNone( );
89   vtkTextProperty* textprop = this->TextActor->GetTextProperty( );
90   textprop->SetColor( 1, 1, 1 );
91   textprop->SetFontFamilyToCourier( );
92   textprop->SetFontSize( 18 );
93   textprop->BoldOff( );
94   textprop->ItalicOff( );
95   textprop->ShadowOff( );
96   textprop->SetJustificationToLeft( );
97   textprop->SetVerticalJustificationToBottom( );
98   vtkCoordinate* coord = this->TextActor->GetPositionCoordinate( );
99   coord->SetCoordinateSystemToNormalizedViewport( );
100   coord->SetValue( 0.01, 0.01 );
101 }
102
103 // -------------------------------------------------------------------------
104 vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
105 GetStyle( )
106 {
107   return( this->Style.GetPointer( ) );
108 }
109
110 // -------------------------------------------------------------------------
111 const vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
112 GetStyle( ) const
113 {
114   return( this->Style.GetPointer( ) );
115 }
116
117 // -------------------------------------------------------------------------
118 void cpExtensions::Visualization::ImageSliceActors::
119 PushActorsInto( vtkRenderer* renderer )
120 {
121   unsigned int N = this->GetNumberOfImageActors( );
122   for( unsigned int n = 0; n < N; ++n )
123     renderer->AddActor( this->GetImageActor( n ) );
124   renderer->AddActor( this->GetTextActor( ) );
125   renderer->AddActor( this->GetPlaneActor( ) );
126   renderer->Modified( );
127 }
128
129 // -------------------------------------------------------------------------
130 void cpExtensions::Visualization::ImageSliceActors::
131 PopActorsFrom( vtkRenderer* renderer )
132 {
133   unsigned int N = this->GetNumberOfImageActors( );
134   for( unsigned int n = 0; n < N; ++n )
135     renderer->RemoveActor( this->GetImageActor( n ) );
136   renderer->RemoveActor( this->GetTextActor( ) );
137   renderer->RemoveActor( this->GetPlaneActor( ) );
138   renderer->Modified( );
139 }
140
141 // -------------------------------------------------------------------------
142 unsigned int cpExtensions::Visualization::ImageSliceActors::
143 GetNumberOfImageActors( ) const
144 {
145   return( this->ImageActors.size( ) );
146 }
147
148 // -------------------------------------------------------------------------
149 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
150 GetImageActor( unsigned int id )
151 {
152   if( id < this->ImageActors.size( ) )
153     return( this->ImageActors[ id ] );
154   else
155     return( NULL );
156 }
157
158 // -------------------------------------------------------------------------
159 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
160 GetImageActor( unsigned int id ) const
161 {
162   if( id < this->ImageActors.size( ) )
163     return( this->ImageActors[ id ] );
164   else
165     return( NULL );
166 }
167
168 // -------------------------------------------------------------------------
169 vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
170 GetTextActor( )
171 {
172   return( this->TextActor );
173 }
174
175 // -------------------------------------------------------------------------
176 const vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
177 GetTextActor( ) const
178 {
179   return( this->TextActor );
180 }
181
182 // -------------------------------------------------------------------------
183 vtkActor* cpExtensions::Visualization::ImageSliceActors::
184 GetPlaneActor( )
185 {
186   return( this->PlaneActor );
187 }
188
189 // -------------------------------------------------------------------------
190 const vtkActor* cpExtensions::Visualization::ImageSliceActors::
191 GetPlaneActor( ) const
192 {
193   return( this->PlaneActor );
194 }
195
196 // -------------------------------------------------------------------------
197 vtkPlane* cpExtensions::Visualization::ImageSliceActors::
198 GetPlaneFunction( )
199 {
200   return( this->PlaneFunction );
201 }
202
203 // -------------------------------------------------------------------------
204 const vtkPlane* cpExtensions::Visualization::ImageSliceActors::
205 GetPlaneFunction( ) const
206 {
207   return( this->PlaneFunction );
208 }
209
210 // -------------------------------------------------------------------------
211 void cpExtensions::Visualization::ImageSliceActors::
212 AddActor( vtkAlgorithm* algorithm, vtkActor* actor )
213 {
214   this->AssociatedActors.push_back( TAssociatedActor( algorithm, actor ) );
215   this->AddItem( actor );
216 }
217
218 // -------------------------------------------------------------------------
219 void cpExtensions::Visualization::ImageSliceActors::
220 AddActor( vtkActor* actor )
221 {
222   this->AddActor( NULL, actor );
223 }
224
225 // -------------------------------------------------------------------------
226 void cpExtensions::Visualization::ImageSliceActors::
227 SetInterpolate( bool v )
228 {
229   if( this->Interpolate != v )
230   {
231     for( unsigned int i = 0; i < this->ImageActors.size( ); ++i )
232       this->ImageActors[ i ]->SetInterpolate( v );
233     this->Interpolate = v;
234     this->Modified( );
235
236   } // fi
237 }
238
239 // -------------------------------------------------------------------------
240 void cpExtensions::Visualization::ImageSliceActors::
241 InterpolateOn( )
242 {
243   this->SetInterpolate( true );
244 }
245
246 // -------------------------------------------------------------------------
247 void cpExtensions::Visualization::ImageSliceActors::
248 InterpolateOff( )
249 {
250   this->SetInterpolate( false );
251 }
252
253 // -------------------------------------------------------------------------
254 double* cpExtensions::Visualization::ImageSliceActors::
255 GetDisplayBounds( ) const
256 {
257   if( this->ImageActors.size( ) > 0 )
258     return( this->ImageActors[ 0 ]->GetDisplayBounds( ) );
259   else
260     return( NULL );
261 }
262
263 // -------------------------------------------------------------------------
264 void cpExtensions::Visualization::ImageSliceActors::
265 GetDisplayBounds( double bounds[ 6 ] ) const
266 {
267   if( this->ImageActors.size( ) == 0 )
268   {
269     bounds[ 0 ] = bounds[ 2 ] = bounds[ 4 ] = double( -1 );
270     bounds[ 1 ] = bounds[ 3 ] = bounds[ 5 ] = double( -1 );
271   }
272   else
273     this->ImageActors[ 0 ]->GetDisplayBounds( bounds );
274 }
275
276 // -------------------------------------------------------------------------
277 int cpExtensions::Visualization::ImageSliceActors::
278 GetAxis( ) const
279 {
280   if( this->SliceMappers.size( ) > 0 )
281     return( this->SliceMappers[ 0 ]->GetOrientation( ) );
282   else
283     return( -1 );
284 }
285
286 // -------------------------------------------------------------------------
287 int cpExtensions::Visualization::ImageSliceActors::
288 GetSliceNumber( ) const
289 {
290   if( this->SliceMappers.size( ) > 0 )
291     return( this->SliceMappers[ 0 ]->GetSliceNumber( ) );
292   else
293     return( -1 );
294 }
295
296 // -------------------------------------------------------------------------
297 int cpExtensions::Visualization::ImageSliceActors::
298 GetSliceNumberMinValue( ) const
299 {
300   if( this->SliceMappers.size( ) > 0 )
301     return( this->SliceMappers[ 0 ]->GetSliceNumberMinValue( ) );
302   else
303     return( -1 );
304 }
305
306 // -------------------------------------------------------------------------
307 int cpExtensions::Visualization::ImageSliceActors::
308 GetSliceNumberMaxValue( ) const
309 {
310   if( this->SliceMappers.size( ) > 0 )
311     return( this->SliceMappers[ 0 ]->GetSliceNumberMaxValue( ) );
312   else
313     return( -1 );
314 }
315
316 // -------------------------------------------------------------------------
317 void cpExtensions::Visualization::ImageSliceActors::
318 SetSliceNumber( const int& slice )
319 {
320   unsigned int nImages = this->SliceMappers.size( );
321   if( nImages == 0 )
322     return;
323
324   // Change visualization extent
325   for( unsigned int i = 0; i < nImages; ++i )
326   {
327     this->SliceMappers[ i ]->SetSliceNumber( slice );
328     this->SliceMappers[ i ]->Modified( );
329     this->ImageActors[ i ]->Modified( );
330     this->SliceMappers[ i ]->Update( );
331
332   } // rof
333
334   // Compute plane
335   vtkAlgorithm* algo = this->SliceMappers[ 0 ]->GetInputAlgorithm( );
336   vtkInformation* info = algo->GetOutputInformation( 0 );
337   int ext[ 6 ];
338   double ori[ 3 ], spac[ 3 ], pos[ 3 ];
339   info->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT( ), ext );
340   info->Get( vtkDataObject::ORIGIN( ), ori );
341   info->Get( vtkDataObject::SPACING( ), spac );
342   this->SliceMappers[ 0 ]->GetSlicePlane( )->GetOrigin( pos );
343
344   // Prevent obscuring voxels by offsetting the plane geometry
345   double xbnds[ ] =
346     {
347       ori[ 0 ] + ( spac[ 0 ] * double( ext[ 0 ] ) ),
348       ori[ 0 ] + ( spac[ 0 ] * double( ext[ 1 ] ) )
349     };
350   double ybnds[ ] =
351     {
352       ori[ 1 ] + ( spac[ 1 ] * double( ext[ 2 ] ) ),
353       ori[ 1 ] + ( spac[ 1 ] * double( ext[ 3 ] ) )
354     };
355   double zbnds[ ] =
356     {
357       ori[ 2 ] + ( spac[ 2 ] * double( ext[ 4 ] ) ),
358       ori[ 2 ] + ( spac[ 2 ] * double( ext[ 5 ] ) )
359     };
360
361   if( spac[ 0 ] < double( 0 ) )
362   {
363     double t = xbnds[ 0 ];
364     xbnds[ 0 ] = xbnds[ 1 ];
365     xbnds[ 1 ] = t;
366
367   } // fi
368   if( spac[ 1 ] < double( 0 ) )
369   {
370     double t = ybnds[ 0 ];
371     ybnds[ 0 ] = ybnds[ 1 ];
372     ybnds[ 1 ] = t;
373
374   } // fi
375   if( spac[ 2 ] < double( 0 ) )
376   {
377     double t = zbnds[ 0 ];
378     zbnds[ 0 ] = zbnds[ 1 ];
379     zbnds[ 1 ] = t;
380
381   } // fi
382
383   // Plane function origin
384   this->PlaneFunction->SetOrigin( pos );
385
386   // Configure visualization and implicit plane orientation
387   int axis = this->SliceMappers[ 0 ]->GetOrientation( );
388   this->PlaneActor->GetProperty( )->SetRepresentationToWireframe( );
389   this->PlaneActor->GetProperty( )->SetLineWidth( 2 );
390   vtkPoints* plane_points = this->PlaneSource->GetPoints( );
391   if( axis == 0 ) // YZ, x-normal
392   {
393     this->PlaneFunction->SetNormal( 1, 0, 0 );
394     plane_points->SetPoint( 0, pos[ 0 ], ybnds[ 0 ], zbnds[ 0 ] );
395     plane_points->SetPoint( 1, pos[ 0 ], ybnds[ 1 ], zbnds[ 0 ] );
396     plane_points->SetPoint( 2, pos[ 0 ], ybnds[ 1 ], zbnds[ 1 ] );
397     plane_points->SetPoint( 3, pos[ 0 ], ybnds[ 0 ], zbnds[ 1 ] );
398     this->PlaneActor->GetProperty( )->SetColor( 1, 0, 0 );
399   }
400   else if( axis == 1 ) // ZX, y-normal
401   {
402     this->PlaneFunction->SetNormal( 0, 1, 0 );
403     plane_points->SetPoint( 0, xbnds[ 0 ], pos[ 1 ], zbnds[ 0 ] );
404     plane_points->SetPoint( 1, xbnds[ 0 ], pos[ 1 ], zbnds[ 1 ] );
405     plane_points->SetPoint( 2, xbnds[ 1 ], pos[ 1 ], zbnds[ 1 ] );
406     plane_points->SetPoint( 3, xbnds[ 1 ], pos[ 1 ], zbnds[ 0 ] );
407     this->PlaneActor->GetProperty( )->SetColor( 0, 1, 0 );
408   }
409   else // XY, z-normal
410   {
411     this->PlaneFunction->SetNormal( 0, 0, 1 );
412     plane_points->SetPoint( 0, xbnds[ 0 ], ybnds[ 0 ], pos[ 2 ] );
413     plane_points->SetPoint( 1, xbnds[ 1 ], ybnds[ 0 ], pos[ 2 ] );
414     plane_points->SetPoint( 2, xbnds[ 1 ], ybnds[ 1 ], pos[ 2 ] );
415     plane_points->SetPoint( 3, xbnds[ 0 ], ybnds[ 1 ], pos[ 2 ] );
416     this->PlaneActor->GetProperty( )->SetColor( 0, 0, 1 );
417
418   } // fi
419   this->PlaneFunction->Modified( );
420   this->PlaneSource->Modified( );
421   this->PlaneMapper->Modified( );
422   this->PlaneActor->Modified( );
423
424   // Prepare other actors to update
425   /* TODO
426      for( unsigned int i = 0; i < this->OtherActors.size( ); ++i )
427      {
428      if( this->OtherActors[ i ].first.GetPointer( ) != NULL )
429      {
430      this->OtherActors[ i ].first->Modified( );
431      this->OtherActors[ i ].first->Update( );
432
433      } // fi
434
435      if( this->OtherActors[ i ].second.GetPointer( ) != NULL )
436      {
437      this->OtherActors[ i ].second->GetMapper( )->Modified( );
438      this->OtherActors[ i ].second->Modified( );
439
440      } // fi
441
442      } // rof
443
444      if( this->m_UpdateCommand != NULL )
445      this->m_UpdateCommand( this->m_UpdateData );
446   */
447
448   // Update text
449   this->UpdateText( );
450 }
451
452 // -------------------------------------------------------------------------
453 void cpExtensions::Visualization::ImageSliceActors::
454 UpdateText( )
455 {
456   if( this->SliceMappers.size( ) > 0 )
457   {
458     char axis;
459     int axId = this->SliceMappers[ 0 ]->GetOrientation( );
460     if     ( axId == 0 ) axis = 'X';
461     else if( axId == 1 ) axis = 'Y';
462     else if( axId == 2 ) axis = 'Z';
463
464     std::sprintf(
465       this->TextBuffer, "Axis: %c (%d)",
466       axis, this->SliceMappers[ 0 ]->GetSliceNumber( )
467       );
468   }
469   else
470     this->TextBuffer[ 0 ] = '\0';
471   this->TextActor->SetInput( this->TextBuffer );
472   this->TextActor->Modified( );
473   this->Modified( );
474 }
475
476 // -------------------------------------------------------------------------
477 void cpExtensions::Visualization::ImageSliceActors::
478 UpdateText( double pos[ 3 ] )
479 {
480   if( this->SliceMappers.size( ) > 0 )
481   {
482     char axis;
483     int axId = this->SliceMappers[ 0 ]->GetOrientation( );
484     if     ( axId == 0 ) axis = 'X';
485     else if( axId == 1 ) axis = 'Y';
486     else if( axId == 2 ) axis = 'Z';
487
488     vtkImageData* image = this->SliceMappers[ 0 ]->GetInput( );
489
490     int ijk[ 3 ];
491     double pcoords[ 3 ];
492     image->ComputeStructuredCoordinates( pos, ijk, pcoords );
493     {
494       int nScl = image->GetNumberOfScalarComponents( );
495       std::stringstream str;
496       str
497         << "[" << ijk[ 0 ]
498         << "," << ijk[ 1 ]
499         << "," << ijk[ 2 ] << "]=(";
500       str <<
501         image->GetScalarComponentAsFloat(
502           ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], 0
503           );
504       for( int n = 1; n < nScl; ++n )
505         str
506           << " "
507           << image->GetScalarComponentAsFloat(
508             ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], n
509             );
510       str << ")";
511       std::sprintf(
512         this->TextBuffer, "Axis: %c (%d) | Pixel %s",
513         axis,
514         this->SliceMappers[ 0 ]->GetSliceNumber( ),
515         str.str( ).c_str( )
516         );
517
518     } // fi
519   }
520   else
521     this->TextBuffer[ 0 ] = '\0';
522   this->TextActor->SetInput( this->TextBuffer );
523   this->TextActor->Modified( );
524   this->Modified( );
525 }
526
527 // -------------------------------------------------------------------------
528 void cpExtensions::Visualization::ImageSliceActors::
529 UpdateText( const double& w, const double& l )
530 {
531   if( this->SliceMappers.size( ) > 0 )
532   {
533     char axis;
534     int axId = this->SliceMappers[ 0 ]->GetOrientation( );
535     if     ( axId == 0 ) axis = 'X';
536     else if( axId == 1 ) axis = 'Y';
537     else if( axId == 2 ) axis = 'Z';
538
539     std::sprintf(
540       this->TextBuffer, "Axis: %c (%d) | W/L (%.2f/%.2f)",
541       axis, this->SliceMappers[ 0 ]->GetSliceNumber( ), w, l
542       );
543   }
544   else
545     this->TextBuffer[ 0 ] = '\0';
546   this->TextActor->SetInput( this->TextBuffer );
547   this->TextActor->Modified( );
548   this->Modified( );
549 }
550
551 // -------------------------------------------------------------------------
552 cpExtensions::Visualization::ImageSliceActors::
553 ImageSliceActors( )
554   : Superclass( ),
555     Interpolate( false )
556 {
557   // Connect this view with a controller
558   this->Style = vtkSmartPointer< ImageInteractorStyle >::New( );
559   this->Style->AssociateView( this );
560   this->Style->SetMouseMoveCommand( Self::_MouseMoveCommand );
561   this->Style->SetMouseClickCommand( Self::_MouseClickCommand );
562   this->Style->SetMouseDoubleClickCommand( Self::_MouseDoubleClickCommand );
563   this->Style->SetMouseWheelCommand( Self::_MouseWheelCommand );
564   this->Style->SetKeyCommand( Self::_KeyCommand );
565
566   this->Clear( );
567 }
568
569 // -------------------------------------------------------------------------
570 cpExtensions::Visualization::ImageSliceActors::
571 ~ImageSliceActors( )
572 {
573 }
574
575 // -------------------------------------------------------------------------
576 void cpExtensions::Visualization::ImageSliceActors::
577 _ConfigureNewInput( int axis )
578 {
579   unsigned int nImages = this->ImageActors.size( );
580
581   // Configure mapper
582   vtkImageSliceMapper* mapper = this->SliceMappers[ nImages ];
583   if( nImages == 0 )
584     mapper->SetOrientation( axis );
585   else
586     mapper->SetOrientation( this->SliceMappers[ 0 ]->GetOrientation( ) );
587   mapper->Update( );
588
589   // Create actor
590   vtkSmartPointer< vtkImageActor > actor =
591     vtkSmartPointer< vtkImageActor >::New( );
592   this->ImageActors.push_back( actor );
593   actor->SetMapper( mapper );
594   actor->SetInterpolate( this->Interpolate );
595   actor->Modified( );
596
597   if( nImages == 0 )
598   {
599     this->AddItem( this->TextActor );
600     this->AddItem( this->PlaneActor );
601     this->Style->AssociateImageActor( actor );
602
603   } // fi
604   this->AddItem( actor );
605
606   if( nImages > 1 )
607     this->SetSliceNumber( this->GetSliceNumber( ) );
608   this->Modified( );
609 }
610
611 // -------------------------------------------------------------------------
612 void cpExtensions::Visualization::ImageSliceActors::
613 _MouseMoveCommand(
614   void* data,
615   const ImageInteractorStyle::ButtonID& btn, double* pos,
616   bool alt, bool ctr, bool sft
617   )
618 {
619   ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
620   if( actors == NULL )
621     return;
622
623   if( btn == ImageInteractorStyle::ButtonID_None )
624   {
625     actors->UpdateText( pos );
626   }
627   else if( btn == ImageInteractorStyle::ButtonID_Left )
628   {
629   }
630   else if( btn == ImageInteractorStyle::ButtonID_Middle )
631   {
632   }
633   else if( btn == ImageInteractorStyle::ButtonID_Right )
634   {
635   } // fi
636 }
637
638 // -------------------------------------------------------------------------
639 void cpExtensions::Visualization::ImageSliceActors::
640 _MouseClickCommand(
641   void* data,
642   const ImageInteractorStyle::ButtonID& btn, double* pos,
643   bool alt, bool ctr, bool sft
644   )
645 {
646 }
647
648 // -------------------------------------------------------------------------
649 void cpExtensions::Visualization::ImageSliceActors::
650 _MouseDoubleClickCommand(
651   void* data,
652   const ImageInteractorStyle::ButtonID& btn, double* pos,
653   bool alt, bool ctr, bool sft
654   )
655 {
656 }
657
658 // -------------------------------------------------------------------------
659 void cpExtensions::Visualization::ImageSliceActors::
660 _MouseWheelCommand(
661   void* data,
662   const int& dir, bool alt, bool ctr, bool sft
663   )
664 {
665 }
666
667 // -------------------------------------------------------------------------
668 void cpExtensions::Visualization::ImageSliceActors::
669 _KeyCommand(
670   void* data,
671   const char& key
672   )
673 {
674 }
675
676 // eof - $RCSfile$