]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Visualization/MPRActors.cxx
Windows updated.
[cpPlugins.git] / lib / cpExtensions / Visualization / MPRActors.cxx
1 #include <cpExtensions/Visualization/MPRActors.h>
2
3 #include <cmath>
4
5 #include <vtkAlgorithmOutput.h>
6 #include <vtkImageData.h>
7 #include <vtkInformation.h>
8 #include <vtkLookupTable.h>
9 #include <vtkOutlineSource.h>
10 #include <vtkProperty.h>
11 #include <vtkRenderer.h>
12 #include <vtkWindowLevelLookupTable.h>
13
14 // -------------------------------------------------------------------------
15 cpExtensions::Visualization::MPRActors*
16 cpExtensions::Visualization::MPRActors::
17 New( )
18 {
19   return( new Self( ) );
20 }
21
22 // -------------------------------------------------------------------------
23 cpExtensions::Visualization::
24 ImageSliceActors* cpExtensions::Visualization::MPRActors::
25 GetSliceActors( const int& i ) const
26 {
27   if( i < 3 )
28     return( this->Slices[ 0 ][ i ] );
29   else
30     return( NULL );
31 }
32
33 // -------------------------------------------------------------------------
34 int cpExtensions::Visualization::MPRActors::
35 AddInputConnection( vtkAlgorithmOutput* aout )
36 {
37   int N = this->ImageMaps.size( );
38   if( N == 0 )
39   {
40     this->ImageMaps.push_back(
41       vtkSmartPointer< vtkImageMapToColors >::New( )
42       );
43     this->ImageMaps[ 0 ]->SetInputConnection( aout );
44     this->SetLookupTableToWindowLevel( 0 );
45     this->_Update( 0 );
46     this->ResetWindowLevel( 0 );
47     return( 0 );
48   }
49   else
50   {
51     // Check if the image share the same space
52     vtkImageData* ref_image = this->_Image( 0 );
53     vtkImageData* new_image =
54       vtkImageData::SafeDownCast(
55         aout->GetProducer( )->GetOutputInformation( 0 )->
56         Get( vtkDataObject::DATA_OBJECT( ) )
57         );
58     int ref_ext[ 6 ], new_ext[ 6 ];
59     ref_image->GetExtent( ref_ext );
60     new_image->GetExtent( new_ext );
61     if(
62       ref_ext[ 0 ] == new_ext[ 0 ] && ref_ext[ 1 ] == new_ext[ 1 ] &&
63       ref_ext[ 2 ] == new_ext[ 2 ] && ref_ext[ 3 ] == new_ext[ 3 ] &&
64       ref_ext[ 4 ] == new_ext[ 4 ] && ref_ext[ 5 ] == new_ext[ 5 ]
65       )
66     {
67       this->ImageMaps.push_back(
68         vtkSmartPointer< vtkImageMapToColors >::New( )
69         );
70       this->ImageMaps[ N ]->SetInputConnection( aout );
71       this->SetLookupTableToColor(
72         N, double( 1 ), double( 0 ), double( 0 )
73         );
74       this->_Update( N );
75       return( N );
76     }
77     else
78       return( -1 );
79
80   } // fi
81 }
82
83 // -------------------------------------------------------------------------
84 int cpExtensions::Visualization::MPRActors::
85 AddInputData( vtkImageData* image )
86 {
87   int N = this->ImageMaps.size( );
88   if( N == 0 )
89   {
90     this->ImageMaps.push_back(
91       vtkSmartPointer< vtkImageMapToColors >::New( )
92       );
93     this->ImageMaps[ 0 ]->SetInputData( image );
94     this->SetLookupTableToWindowLevel( 0 );
95     this->_Update( 0 );
96     this->ResetWindowLevel( 0 );
97     return( 0 );
98   }
99   else
100   {
101     // Check if the image share the same space
102     vtkImageData* ref_image = this->_Image( 0 );
103     vtkImageData* new_image = image;
104     int ref_ext[ 6 ], new_ext[ 6 ];
105     ref_image->GetExtent( ref_ext );
106     new_image->GetExtent( new_ext );
107     if(
108       ref_ext[ 0 ] == new_ext[ 0 ] && ref_ext[ 1 ] == new_ext[ 1 ] &&
109       ref_ext[ 2 ] == new_ext[ 2 ] && ref_ext[ 3 ] == new_ext[ 3 ] &&
110       ref_ext[ 4 ] == new_ext[ 4 ] && ref_ext[ 5 ] == new_ext[ 5 ]
111       )
112     {
113       this->ImageMaps.push_back(
114         vtkSmartPointer< vtkImageMapToColors >::New( )
115         );
116       this->ImageMaps[ N ]->SetInputData( image );
117       this->SetLookupTableToColor(
118         N, double( 1 ), double( 0 ), double( 0 )
119         );
120       this->_Update( N );
121       return( N );
122     }
123     else
124       return( -1 );
125
126   } // fi
127 }
128
129 // -------------------------------------------------------------------------
130 void cpExtensions::Visualization::MPRActors::
131 PushDataInto( vtkRenderer* x, vtkRenderer* y, vtkRenderer* z, vtkRenderer* w )
132 {
133   vtkRenderer* rends[] = { x, y, z };
134   for( int i = 0; i < 3; ++i )
135   {
136     if( rends[ i ] != NULL )
137     {
138       for(
139         unsigned int k = 0;
140         k < this->Slices[ 0 ][ i ]->GetNumberOfImageActors( );
141         ++k
142         )
143         rends[ i ]->AddActor( this->Slices[ 0 ][ i ]->GetImageActor( k ) );
144       rends[ i ]->AddActor( this->Slices[ 0 ][ i ]->GetTextActor( ) );
145       for( int j = 0; j < 3; ++j )
146         rends[ i ]->AddActor( this->Slices[ 0 ][ j ]->GetPlaneActor( ) );
147
148     } // fi
149     if( w != NULL )
150     {
151       for(
152         unsigned int k = 0;
153         k < this->Slices[ 1 ][ i ]->GetNumberOfImageActors( );
154         ++k
155         )
156         w->AddActor( this->Slices[ 1 ][ i ]->GetImageActor( k ) );
157       w->AddActor( this->Slices[ 1 ][ i ]->GetPlaneActor( ) );
158
159     } // fi
160
161   } // rof
162   if( w != NULL )
163     w->AddActor( this->ImageOutlineActor );
164 }
165
166 // -------------------------------------------------------------------------
167 void cpExtensions::Visualization::MPRActors::
168 PopDataFrom(
169   vtkRenderer* x,
170   vtkRenderer* y,
171   vtkRenderer* z,
172   vtkRenderer* w
173   )
174 {
175   vtkRenderer* rends[] = { x, y, z };
176   for( int i = 0; i < 3; ++i )
177   {
178     if( rends[ i ] != NULL )
179     {
180       for(
181         unsigned int k = 0;
182         k < this->Slices[ 0 ][ i ]->GetNumberOfImageActors( );
183         ++k
184         )
185         rends[ i ]->RemoveActor( this->Slices[ 0 ][ i ]->GetImageActor( k ) );
186       rends[ i ]->RemoveActor( this->Slices[ 0 ][ i ]->GetTextActor( ) );
187       for( int j = 0; j < 3; ++j )
188         rends[ i ]->RemoveActor( this->Slices[ 0 ][ j ]->GetPlaneActor( ) );
189
190     } // fi
191     if( w != NULL )
192     {
193       for(
194         unsigned int k = 0;
195         k < this->Slices[ 1 ][ i ]->GetNumberOfImageActors( );
196         ++k
197         )
198         w->RemoveActor( this->Slices[ 1 ][ i ]->GetImageActor( k ) );
199       w->RemoveActor( this->Slices[ 1 ][ i ]->GetPlaneActor( ) );
200
201     } // fi
202
203   } // rof
204   if( w != NULL )
205     w->RemoveActor( this->ImageOutlineActor );
206 }
207
208 // -------------------------------------------------------------------------
209 void cpExtensions::Visualization::MPRActors::
210 LinkInteractors( )
211 {
212   this->_Update( 0 );
213   this->_Update( 1 );
214   this->_Update( 2 );
215 }
216
217 // -------------------------------------------------------------------------
218 void cpExtensions::Visualization::MPRActors::
219 SetLookupTable( unsigned int i, vtkScalarsToColors* lut )
220 {
221   if( i < this->ImageMaps.size( ) )
222   {
223     this->ImageMaps[ i ]->SetLookupTable( lut );
224     this->ImageMaps[ i ]->Update( );
225     this->Modified( );
226
227   } // fi
228 }
229
230 // -------------------------------------------------------------------------
231 vtkScalarsToColors* cpExtensions::Visualization::MPRActors::
232 GetLookupTable( unsigned int i ) const
233 {
234   if( i < this->ImageMaps.size( ) )
235     return( this->ImageMaps[ i ]->GetLookupTable( ) );
236   else
237     return( NULL );
238 }
239
240 // -------------------------------------------------------------------------
241 void cpExtensions::Visualization::MPRActors::
242 SetLookupTableToWindowLevel( unsigned int i )
243 {
244   // Check if the input has been configured
245   vtkImageData* image = this->_Image( i );
246   if( image == NULL )
247     return;
248
249   double r[ 2 ];
250   image->GetScalarRange( r );
251
252   vtkSmartPointer< vtkWindowLevelLookupTable > lut =
253     vtkSmartPointer< vtkWindowLevelLookupTable >::New( );
254   lut->SetScaleToLinear( );
255   lut->SetTableRange( r );
256   lut->Build( );
257
258   this->SetLookupTable( i, lut );
259 }
260
261 // -------------------------------------------------------------------------
262 double cpExtensions::Visualization::MPRActors::
263 GetMinWindow( unsigned int i ) const
264 {
265   return( 0 );
266 }
267
268 // -------------------------------------------------------------------------
269 double cpExtensions::Visualization::MPRActors::
270 GetMaxWindow( unsigned int i ) const
271 {
272   // Check if the input has been configured
273   vtkImageData* image = this->_Image( i );
274   if( image == NULL )
275     return( double( 0 ) );
276
277   double r[ 2 ];
278   image->GetScalarRange( r );
279   return( r[ 1 ] - r[ 0 ] );
280 }
281
282 // -------------------------------------------------------------------------
283 double cpExtensions::Visualization::MPRActors::
284 GetMinLevel( unsigned int i ) const
285 {
286   // Check if the input has been configured
287   vtkImageData* image = this->_Image( i );
288   if( image == NULL )
289     return( double( 0 ) );
290
291   double r[ 2 ];
292   image->GetScalarRange( r );
293   return( r[ 0 ] );
294 }
295
296 // -------------------------------------------------------------------------
297 double cpExtensions::Visualization::MPRActors::
298 GetMaxLevel( unsigned int i ) const
299 {
300   // Check if the input has been configured
301   vtkImageData* image = this->_Image( i );
302   if( image == NULL )
303     return( double( 0 ) );
304
305   double r[ 2 ];
306   image->GetScalarRange( r );
307   return( r[ 1 ] );
308 }
309
310 // -------------------------------------------------------------------------
311 double cpExtensions::Visualization::MPRActors::
312 GetWindow( unsigned int i ) const
313 {
314   vtkWindowLevelLookupTable* lut =
315     dynamic_cast< vtkWindowLevelLookupTable* >( this->GetLookupTable( i ) );
316   if( lut != NULL )
317     return( lut->GetWindow( ) );
318   else
319     return( double( 0 ) );
320 }
321
322 // -------------------------------------------------------------------------
323 double cpExtensions::Visualization::MPRActors::
324 GetLevel( unsigned int i ) const
325 {
326   vtkWindowLevelLookupTable* lut =
327     dynamic_cast< vtkWindowLevelLookupTable* >( this->GetLookupTable( i ) );
328   if( lut != NULL )
329     return( lut->GetLevel( ) );
330   else
331     return( double( 0 ) );
332 }
333
334 // -------------------------------------------------------------------------
335 void cpExtensions::Visualization::MPRActors::
336 SetWindow( unsigned int i, const double& w )
337 {
338   vtkWindowLevelLookupTable* lut =
339     dynamic_cast< vtkWindowLevelLookupTable* >( this->GetLookupTable( i ) );
340   if( lut != NULL )
341   {
342     lut->SetWindow( w );
343     lut->Build( );
344     this->ImageMaps[ i ]->Modified( );
345     this->Modified( );
346
347   } // fi
348 }
349
350 // -------------------------------------------------------------------------
351 void cpExtensions::Visualization::MPRActors::
352 SetLevel( unsigned int i, const double& l )
353 {
354   vtkWindowLevelLookupTable* lut =
355     dynamic_cast< vtkWindowLevelLookupTable* >( this->GetLookupTable( i ) );
356   if( lut != NULL )
357   {
358     lut->SetLevel( l );
359     lut->Build( );
360     this->ImageMaps[ i ]->Modified( );
361     this->Modified( );
362
363   } // fi
364 }
365
366 // -------------------------------------------------------------------------
367 void cpExtensions::Visualization::MPRActors::
368 SetWindowLevel( unsigned int i, const double& w, const double& l )
369 {
370   vtkWindowLevelLookupTable* lut =
371     dynamic_cast< vtkWindowLevelLookupTable* >( this->GetLookupTable( i ) );
372   if( lut != NULL )
373   {
374     lut->SetWindow( w );
375     lut->SetLevel( l );
376     lut->Build( );
377     this->ImageMaps[ i ]->Modified( );
378
379     for( unsigned int j = 0; j < 3; ++j )
380       this->Slices[ 0 ][ j ]->UpdateText( w, l );
381
382     this->Modified( );
383
384   } // fi
385 }
386
387 // -------------------------------------------------------------------------
388 void cpExtensions::Visualization::MPRActors::
389 ResetWindowLevel( unsigned int i )
390 {
391   vtkImageData* image = this->_Image( i );
392   vtkWindowLevelLookupTable* lut =
393     dynamic_cast< vtkWindowLevelLookupTable* >( this->GetLookupTable( i ) );
394   if( image != NULL && lut != NULL )
395   {
396     double r[ 2 ];
397     image->GetScalarRange( r );
398     lut->SetTableRange( r );
399     lut->SetWindow( r[ 1 ] - r[ 0 ] );
400     lut->SetLevel( ( r[ 1 ] + r[ 0 ] ) / double( 2 ) );
401     lut->Build( );
402     this->ImageMaps[ i ]->Modified( );
403     this->Modified( );
404
405   } // fi
406 }
407
408 // -------------------------------------------------------------------------
409 void cpExtensions::Visualization::MPRActors::
410 SetLookupTableToColor(
411   unsigned int i, const double& r, const double& g, const double& b
412   )
413 {
414   static const double _0 = double( 0 );
415   static const double _1 = double( 1 );
416   static const double _2 = double( 2 );
417   static const double _4 = double( 4 );
418   static const double _6 = double( 6 );
419   static const double _OPACITY = double( 0.6 );
420
421   // Check if the input has been configured
422   vtkImageData* image = this->_Image( i );
423   if( image == NULL )
424     return;
425
426   double range[ 2 ];
427   image->GetScalarRange( range );
428
429   // Get HSV from display color
430   double cmax = ( r > g )? r: g; cmax = ( b > cmax )? b: cmax;
431   double cmin = ( r < g )? r: g; cmin = ( b < cmin )? b: cmin;
432   double d = cmax - cmin;
433
434   double saturation = ( std::fabs( cmax ) > _0 )? d / cmax: _0;
435   double value = cmax;
436   double hue = _0;
437   if( d > _0 )
438   {
439     if( r == cmax )
440       hue = std::fmod( ( g - b ) / d, _6 );
441     else if( g == cmax )
442       hue = ( ( b - r ) / d ) + _2;
443     else if( b == cmax )
444       hue = ( ( r - g ) / d ) + _4;
445     hue *= _1 / _6;
446     
447   } // fi
448
449   // Define new lookup table
450   vtkSmartPointer< vtkLookupTable > lut =
451     vtkSmartPointer< vtkLookupTable >::New( );
452   lut->SetScaleToLinear( );
453   /*
454     lut->SetAboveRangeColor( _0, _0, _0, _0 );
455     lut->SetBelowRangeColor( _0, _0, _0, _0 );
456   */
457   lut->SetNanColor( _0, _0, _0, _0 );
458   lut->SetTableRange( range[ 0 ], range[ 1 ] );
459   lut->SetAlphaRange( _0, _OPACITY );
460   lut->SetHueRange( _0, hue );
461   lut->SetSaturationRange( _0, saturation );
462   lut->SetValueRange( _0, value );
463   lut->Build( );
464
465   this->SetLookupTable( i, lut );
466 }
467
468 // -------------------------------------------------------------------------
469 int cpExtensions::Visualization::MPRActors::
470 GetSliceNumberMinValue( const int& axis ) const
471 {
472   return( this->Slices[ 0 ][ axis ]->GetSliceNumberMinValue( ) );
473 }
474
475 // -------------------------------------------------------------------------
476 int cpExtensions::Visualization::MPRActors::
477 GetSliceNumberMaxValue( const int& axis ) const
478 {
479   return( this->Slices[ 0 ][ axis ]->GetSliceNumberMaxValue( ) );
480 }
481
482 // -------------------------------------------------------------------------
483 int cpExtensions::Visualization::MPRActors::
484 GetSlice( const int& axis ) const
485 {
486   return( this->Slices[ 0 ][ axis ]->GetSliceNumber( ) );
487 }
488
489 // -------------------------------------------------------------------------
490 void cpExtensions::Visualization::MPRActors::
491 SetSlice( const int& axis, const int& slice )
492 {
493   vtkImageData* image = this->_Image( 0 );
494   if( image == NULL )
495     return;
496
497   // Get image data extent
498   int ext[ 6 ];
499   image->GetExtent( ext );
500
501   // Check if the slice is valid
502   int real = slice;
503   if( slice < ext[ axis << 1 ] )
504     real = ext[ axis << 1 ];
505   if( ext[ ( axis << 1 ) + 1 ] < slice )
506     real = ext[ ( axis << 1 ) + 1 ];
507
508   // Change slice
509   this->Slices[ 0 ][ axis ]->SetSliceNumber( real );
510   this->Slices[ 1 ][ axis ]->SetSliceNumber( real );
511   this->Modified( );
512 }
513
514 // -------------------------------------------------------------------------
515 void cpExtensions::Visualization::MPRActors::
516 SetSlice( const int& axis, const double& slice )
517 {
518   vtkImageData* image = this->_Image( 0 );
519   if( image == NULL )
520     return;
521
522   double x[ 3 ] = { double( 0 ) };
523   double pcoords[ 3 ];
524   int ijk[ 3 ];
525
526   x[ axis ] = slice;
527   image->ComputeStructuredCoordinates( x, ijk, pcoords );
528   this->SetSlice( axis, ijk[ axis ] );
529 }
530
531 // -------------------------------------------------------------------------
532 void cpExtensions::Visualization::MPRActors::
533 ResetSlices( )
534 {
535   for( unsigned int i = 0; i < 2; ++i )
536     for( unsigned int j = 0; j < 3; ++j )
537       this->Slices[ i ][ j ]->SetSliceNumber(
538         this->Slices[ i ][ j ]->GetSliceNumberMinValue( )
539         );
540 }
541
542 // -------------------------------------------------------------------------
543 cpExtensions::Visualization::MPRActors::
544 MPRActors( )
545   : Superclass( )
546 {
547   this->ImageOutlineActor = vtkSmartPointer< vtkActor >::New( );
548   for( unsigned int i = 0; i < 2; ++i )
549     for( unsigned int j = 0; j < 3; ++j )
550       this->Slices[ i ][ j ] = vtkSmartPointer< ImageSliceActors >::New( );
551 }
552
553 // -------------------------------------------------------------------------
554 cpExtensions::Visualization::MPRActors::
555 ~MPRActors( )
556 {
557 }
558
559 // -------------------------------------------------------------------------
560 vtkImageData* cpExtensions::Visualization::MPRActors::
561 _Image( unsigned int i ) const
562 {
563   if( i < this->ImageMaps.size( ) )
564   {
565     vtkAlgorithm* algo = this->ImageMaps[ i ]->GetInputAlgorithm( );
566     vtkInformation* info = algo->GetOutputInformation( 0 );
567     return(
568       vtkImageData::SafeDownCast(
569         info->Get( vtkDataObject::DATA_OBJECT( ) )
570         )
571       );
572   }
573   else
574     return( NULL );
575 }
576
577 // -------------------------------------------------------------------------
578 void cpExtensions::Visualization::MPRActors::
579 _Update( unsigned int i )
580 {
581   // Check if the input has been configured
582   vtkImageData* image = this->_Image( i );
583   if( image == NULL )
584     return;
585   this->ImageMaps[ i ]->Update( );
586
587   for( int j = 0; j < 2; ++j )
588   {
589     for( int k = 0; k < 3; ++k )
590     {
591       this->Slices[ j ][ k ]->AddInputConnection(
592         this->ImageMaps[ i ]->GetOutputPort( ), k
593         );
594       this->Slices[ j ][ k ]->UpdateText( );
595
596       // Add all of slice's props
597       this->Slices[ j ][ k ]->InitTraversal( );
598       vtkProp* prop = this->Slices[ j ][ k ]->GetNextProp( );
599       while( prop != NULL )
600       {
601         this->AddItem( prop );
602         prop = this->Slices[ j ][ k ]->GetNextProp( );
603
604       } // elihw
605
606     } // rof
607
608   } // rof
609
610   if( i == 0 )
611   {
612     // Create 3D outline
613     double bb[ 6 ];
614     image->GetBounds( bb );
615
616     vtkSmartPointer< vtkOutlineSource > img_ol =
617       vtkSmartPointer< vtkOutlineSource >::New( );
618     img_ol->SetBounds( bb );
619
620     vtkSmartPointer< vtkPolyDataMapper > img_ol_mapper =
621       vtkSmartPointer< vtkPolyDataMapper >::New( );
622     img_ol_mapper->SetInputConnection( img_ol->GetOutputPort( ) );
623     this->ImageOutlineActor->SetMapper( img_ol_mapper );
624     this->ImageOutlineActor->GetProperty( )->SetColor( 1, 1, 1 );
625     this->ImageOutlineActor->GetProperty( )->SetLineWidth( 1 );
626
627     this->AddItem( this->ImageOutlineActor );
628
629   } // fi
630 }
631
632 // eof - $RCSfile$