1 #include <cpExtensions/Interaction/ImageSliceStyle.h>
2 #include <cpExtensions/Visualization/CursorActors.h>
3 #include <cpExtensions/Visualization/LUTImageActor.h>
4 #include <cpExtensions/Visualization/WindowLevelImageActor.h>
5 #include <vtkAssemblyPath.h>
6 #include <vtkCommand.h>
7 #include <vtkImageData.h>
8 #include <vtkImageSlice.h>
9 #include <vtkProperty.h>
10 #include <vtkPropCollection.h>
11 #include <vtkPropPicker.h>
12 #include <vtkRenderer.h>
13 #include <vtkRenderWindowInteractor.h>
14 #include <vtkTextActor.h>
15 #include <vtkTextProperty.h>
18 // -------------------------------------------------------------------------
19 cpExtensions::Interaction::ImageSliceStyle::
20 Self* cpExtensions::Interaction::ImageSliceStyle::
23 return( new Self( ) );
26 // -------------------------------------------------------------------------
27 int cpExtensions::Interaction::ImageSliceStyle::
28 GetSliceNumber( ) const
30 if( this->m_WLActor.GetPointer( ) != NULL )
31 return( this->m_WLActor->GetSliceNumber( ) );
36 // -------------------------------------------------------------------------
37 int cpExtensions::Interaction::ImageSliceStyle::
38 GetOrientation( ) const
40 if( this->m_WLActor.GetPointer( ) != NULL )
41 return( this->m_WLActor->GetOrientation( ) );
46 // -------------------------------------------------------------------------
47 void cpExtensions::Interaction::ImageSliceStyle::
50 static bool cursor_visible = false;
54 if( this->_PickPointOnImageActor( idx, pnt ) )
56 this->m_Cursor->SetCursor( pnt, false );
57 this->_ShowText( pnt );
60 this->m_Cursor->VisibilityOn( );
61 this->m_Text->VisibilityOn( );
62 cursor_visible = true;
65 this->Interactor->Render( );
71 this->m_Cursor->VisibilityOff( );
72 this->m_Text->VisibilityOff( );
73 cursor_visible = false;
74 this->Interactor->Render( );
80 this->Overclass::OnMouseMove( );
83 // -------------------------------------------------------------------------
84 void cpExtensions::Interaction::ImageSliceStyle::
85 OnMouseWheelForward( )
88 if( this->m_WLActor.GetPointer( ) == NULL )
90 s = this->m_WLActor->GetSliceNumber( );
91 s += ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
92 this->m_WLActor->SetSliceNumber( s );
93 s = this->m_WLActor->GetSliceNumber( );
94 if( this->m_LUTActor.GetPointer( ) != NULL )
95 this->m_LUTActor->SetSliceNumber( s );
96 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
97 this->Interactor->Render( );
101 // -------------------------------------------------------------------------
102 void cpExtensions::Interaction::ImageSliceStyle::
103 OnMouseWheelBackward( )
106 if( this->m_WLActor.GetPointer( ) == NULL )
108 s = this->m_WLActor->GetSliceNumber( );
109 s -= ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
110 this->m_WLActor->SetSliceNumber( s );
111 s = this->m_WLActor->GetSliceNumber( );
112 if( this->m_LUTActor.GetPointer( ) != NULL )
113 this->m_LUTActor->SetSliceNumber( s );
114 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
115 this->Interactor->Render( );
116 this->OnMouseMove( );
119 // -------------------------------------------------------------------------
120 void cpExtensions::Interaction::ImageSliceStyle::
123 switch( this->Interactor->GetKeyCode( ) )
127 this->FindPokedRenderer(
128 this->Interactor->GetEventPosition( )[ 0 ],
129 this->Interactor->GetEventPosition( )[ 1 ]
131 this->CurrentRenderer->ResetCamera( );
132 this->Interactor->Render( );
142 cpExtensions::Visualization::ImageViewerActors*
143 cpExtensions::Interaction::ImageSliceStyle::
146 return( this->m_Actors );
149 // -------------------------------------------------------------------------
150 const cpExtensions::Visualization::ImageViewerActors*
151 cpExtensions::Interaction::ImageSliceStyle::
154 return( this->m_Actors );
157 // -------------------------------------------------------------------------
158 void cpExtensions::Interaction::ImageSliceStyle::
159 SetActors( cpExtensions::Visualization::ImageViewerActors* actors )
161 this->m_Actors = actors;
164 this->m_PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
165 this->m_PropPicker->PickFromListOn( );
166 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
168 AddPickList( this->m_Actors->GetWindowLevelImageActor( ) );
171 this->m_PropPicker = NULL;
174 // -------------------------------------------------------------------------
175 void cpExtensions::Interaction::ImageSliceStyle::
178 this->Superclass::OnMouseMove( );
179 if( this->m_Actors.GetPointer( ) == NULL )
184 static double pos[ 3 ];
185 if( this->_PickPosition( idx, pos ) )
188 this->Interactor->GetControlKey( ) == 1 &&
189 this->GetButtonID( ) == Self::ButtonID_Left
192 this->m_Actors->SetSuperCursor( pos, this->m_Actors->GetOrientation( ) == 2 );
193 this->InvokeEvent( vtkCommand::UserEvent + 1, pos );
196 this->m_Actors->SetCursor( pos, this->m_Actors->GetOrientation( ) == 2 );
199 this->m_Actors->HideViewerActors( );
200 this->Interactor->Render( );
203 // -------------------------------------------------------------------------
204 void cpExtensions::Interaction::ImageSliceStyle::
205 OnMouseWheelForward( )
208 if( this->m_Actors.GetPointer( ) == NULL )
210 s = this->m_Actors->GetSliceNumber( );
211 s += ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
212 this->m_Actors->SetSliceNumber( s );
213 s = this->m_Actors->GetSliceNumber( );
214 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
215 this->Interactor->Render( );
216 this->OnMouseMove( );
219 // -------------------------------------------------------------------------
220 void cpExtensions::Interaction::ImageSliceStyle::
221 OnMouseWheelBackward( )
224 if( this->m_Actors.GetPointer( ) == NULL )
226 s = this->m_Actors->GetSliceNumber( );
227 s -= ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
228 this->m_Actors->SetSliceNumber( s );
229 s = this->m_Actors->GetSliceNumber( );
230 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
231 this->Interactor->Render( );
232 this->OnMouseMove( );
235 // -------------------------------------------------------------------------
236 void cpExtensions::Interaction::ImageSliceStyle::
242 // -------------------------------------------------------------------------
243 cpExtensions::Interaction::ImageSliceStyle::
247 this->SetInteractionModeToImage2D( );
248 this->m_PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
249 this->m_PropPicker->PickFromListOn( );
251 this->m_Cursor = vtkSmartPointer< TCursor >::New( );
252 this->m_Cursor->VisibilityOff( );
253 this->m_Cursor->GetProperty( 0 )->SetColor( 1, 1, 0 );
254 this->m_Cursor->GetProperty( 1 )->SetColor( 1, 1, 0 );
257 this->m_TextBuffer[ 0 ] = '\0';
258 this->m_Text = vtkSmartPointer< vtkTextActor >::New( );
259 this->m_Text->SetTextScaleModeToNone( );
260 auto textprop = this->m_Text->GetTextProperty( );
261 textprop->SetColor( 1, 1, 0 );
262 textprop->SetFontFamilyToCourier( );
263 textprop->SetFontSize( 12 );
264 textprop->BoldOff( );
265 textprop->ItalicOff( );
266 textprop->ShadowOff( );
267 textprop->SetJustificationToLeft( );
268 textprop->SetVerticalJustificationToBottom( );
269 auto coord = this->m_Text->GetPositionCoordinate( );
270 coord->SetCoordinateSystemToNormalizedViewport( );
271 coord->SetValue( 0.01, 0.02 );
272 this->m_Text->VisibilityOff( );
275 // -------------------------------------------------------------------------
276 cpExtensions::Interaction::ImageSliceStyle::
281 // -------------------------------------------------------------------------
282 bool cpExtensions::Interaction::ImageSliceStyle::
283 _PickPointOnImageActor( int idx[ 2 ], double pnt[ 3 ] )
285 // Check if data is valid
287 this->Interactor == NULL ||
288 this->CurrentRenderer == NULL ||
289 this->m_PropPicker.GetPointer( ) == NULL
293 // Find the renderer where the event has been raised
294 idx[ 0 ] = this->Interactor->GetEventPosition( )[ 0 ];
295 idx[ 1 ] = this->Interactor->GetEventPosition( )[ 1 ];
296 this->FindPokedRenderer( double( idx[ 0 ] ), double( idx[ 1 ] ) );
298 // Check if the image has changed
299 this->Interactor->GetPicker( )->
300 Pick( idx[ 0 ], idx[ 1 ], 0.0, this->CurrentRenderer );
302 vtkAbstractPropPicker::SafeDownCast( this->Interactor->GetPicker( ) );
305 TWLActor* curr_actor = dynamic_cast< TWLActor* >( picker->GetProp3D( ) );
306 if( curr_actor != this->m_WLActor.GetPointer( ) && curr_actor != NULL )
308 this->m_WLActor = curr_actor;
309 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
310 this->m_PropPicker->AddPickList( curr_actor );
312 auto props = this->CurrentRenderer->GetViewProps( );
313 this->m_LUTActor = NULL;
314 props->InitTraversal( );
316 while( ( ( prop = props->GetNextProp( ) ) != NULL ) && ( this->m_LUTActor.GetPointer( ) == NULL ) )
317 this->m_LUTActor = dynamic_cast< TLUTActor* >( prop );
319 this->m_Cursor->SetImageBounds( curr_actor->GetImage( )->GetBounds( ) );
320 this->m_Cursor->SetImageOrientation( curr_actor->GetOrientation( ) );
321 this->m_Cursor->InitTraversal( );
322 while( vtkProp* prop = this->m_Cursor->GetNextProp( ) )
323 this->CurrentRenderer->AddViewProp( prop );
324 this->CurrentRenderer->AddViewProp( this->m_Text );
327 if( this->m_WLActor.GetPointer( ) == NULL )
329 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
334 // Pick a 3D position
335 int r = this->m_PropPicker->Pick(
336 double( idx[ 0 ] ), double( idx[ 1 ] ), double( 0 ),
337 this->CurrentRenderer
341 this->m_PropPicker->GetPickPosition( pnt );
345 // -------------------------------------------------------------------------
346 void cpExtensions::Interaction::ImageSliceStyle::
347 _CorrectPosition( double pos[ 3 ], int ijk[ 3 ] )
349 if( this->m_WLActor.GetPointer( ) == NULL )
351 auto image = this->m_WLActor->GetImage( );
355 // Approximate image index
357 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
359 // Manually correct index
361 image->GetExtent( ext );
362 for( int i = 0; i < 3; ++i )
364 if( ijk[ i ] < ext[ i << 1 ] )
365 ijk[ i ] = ext[ i << 1 ];
366 if( ext[ ( i << 1 ) + 1 ] < ijk[ i ] )
367 ijk[ i ] = ext[ ( i << 1 ) + 1 ];
371 // Get real coordinates
372 int o = this->m_WLActor->GetOrientation( );
373 ijk[ o ] = this->m_WLActor->GetSliceNumber( );
374 image->GetPoint( image->ComputePointId( ijk ), pos );
377 // -------------------------------------------------------------------------
378 void cpExtensions::Interaction::ImageSliceStyle::
379 _ShowText( double pos[ 3 ] )
381 if( this->m_WLActor.GetPointer( ) == NULL )
383 auto image = this->m_WLActor->GetImage( );
388 this->_CorrectPosition( pos, ijk );
389 int o = this->m_WLActor->GetOrientation( );
391 std::stringstream buffer;
392 buffer << "Axis: " << char( 'X' + char( o ) ) << std::endl;
393 int nScl = image->GetNumberOfScalarComponents( );
395 << "Pixel: [" << ijk[ 0 ]
397 << "," << ijk[ 2 ] << "] = < "
398 << image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], 0 );
399 for( int n = 1; n < nScl; ++n )
402 << image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], n );
403 buffer << " >" << std::endl;
406 << pos[ 0 ] << ", " << pos[ 1 ] << ", " << pos[ 2 ]
408 cpExtensions_SPRINTF( this->m_TextBuffer, 1024, buffer.str( ).c_str( ) );
409 this->m_Text->SetInput( this->m_TextBuffer );
410 this->m_Text->VisibilityOn( );
411 this->m_Text->Modified( );