1 #include <cpExtensions/Utility.h>
2 #include <cpExtensions/Interaction/ImageSliceStyle.h>
3 #include <cpExtensions/Visualization/CursorActors.h>
4 #include <cpExtensions/Visualization/LUTImageActor.h>
5 #include <cpExtensions/Visualization/WindowLevelImageActor.h>
6 #include <vtkAssemblyPath.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 <vtkTextActor.h>
14 #include <vtkTextProperty.h>
18 #include <cpExtensions/Visualization/ImageViewerActors.h>
21 // -------------------------------------------------------------------------
22 cpExtensions::Interaction::ImageSliceStyle::
23 Self* cpExtensions::Interaction::ImageSliceStyle::
26 return( new Self( ) );
29 // -------------------------------------------------------------------------
30 int cpExtensions::Interaction::ImageSliceStyle::
31 GetSliceNumber( ) const
33 if( this->m_WLActor.GetPointer( ) != NULL )
34 return( this->m_WLActor->GetSliceNumber( ) );
39 // -------------------------------------------------------------------------
40 int cpExtensions::Interaction::ImageSliceStyle::
41 GetOrientation( ) const
43 if( this->m_WLActor.GetPointer( ) != NULL )
44 return( this->m_WLActor->GetOrientation( ) );
49 // -------------------------------------------------------------------------
50 void cpExtensions::Interaction::ImageSliceStyle::
53 static bool cursor_visible = false;
57 if( this->_PickPointOnImageActor( idx, pnt ) )
59 this->m_Cursor->SetCursor( pnt, false );
60 this->_ShowText( pnt );
63 this->m_Cursor->VisibilityOn( );
64 this->m_Text->VisibilityOn( );
65 cursor_visible = true;
68 this->Interactor->Render( );
74 this->m_Cursor->VisibilityOff( );
75 this->m_Text->VisibilityOff( );
76 cursor_visible = false;
77 this->Interactor->Render( );
83 this->Overclass::OnMouseMove( );
86 // -------------------------------------------------------------------------
87 void cpExtensions::Interaction::ImageSliceStyle::
88 OnMouseWheelForward( )
91 if( this->m_WLActor.GetPointer( ) == NULL )
93 s = this->m_WLActor->GetSliceNumber( );
94 s += ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
95 this->m_WLActor->SetSliceNumber( s );
96 s = this->m_WLActor->GetSliceNumber( );
97 if( this->m_LUTActor.GetPointer( ) != NULL )
98 this->m_LUTActor->SetSliceNumber( s );
99 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
100 this->Interactor->Render( );
101 this->OnMouseMove( );
104 // -------------------------------------------------------------------------
105 void cpExtensions::Interaction::ImageSliceStyle::
106 OnMouseWheelBackward( )
109 if( this->m_WLActor.GetPointer( ) == NULL )
111 s = this->m_WLActor->GetSliceNumber( );
112 s -= ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
113 this->m_WLActor->SetSliceNumber( s );
114 s = this->m_WLActor->GetSliceNumber( );
115 if( this->m_LUTActor.GetPointer( ) != NULL )
116 this->m_LUTActor->SetSliceNumber( s );
117 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
118 this->Interactor->Render( );
119 this->OnMouseMove( );
122 // -------------------------------------------------------------------------
123 void cpExtensions::Interaction::ImageSliceStyle::
126 switch( this->Interactor->GetKeyCode( ) )
130 this->FindPokedRenderer(
131 this->Interactor->GetEventPosition( )[ 0 ],
132 this->Interactor->GetEventPosition( )[ 1 ]
134 this->CurrentRenderer->ResetCamera( );
135 this->Interactor->Render( );
145 cpExtensions::Visualization::ImageViewerActors*
146 cpExtensions::Interaction::ImageSliceStyle::
149 return( this->m_Actors );
152 // -------------------------------------------------------------------------
153 const cpExtensions::Visualization::ImageViewerActors*
154 cpExtensions::Interaction::ImageSliceStyle::
157 return( this->m_Actors );
160 // -------------------------------------------------------------------------
161 void cpExtensions::Interaction::ImageSliceStyle::
162 SetActors( cpExtensions::Visualization::ImageViewerActors* actors )
164 this->m_Actors = actors;
167 this->m_PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
168 this->m_PropPicker->PickFromListOn( );
169 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
171 AddPickList( this->m_Actors->GetWindowLevelImageActor( ) );
174 this->m_PropPicker = NULL;
177 // -------------------------------------------------------------------------
178 void cpExtensions::Interaction::ImageSliceStyle::
181 this->Superclass::OnMouseMove( );
182 if( this->m_Actors.GetPointer( ) == NULL )
187 static double pos[ 3 ];
188 if( this->_PickPosition( idx, pos ) )
191 this->Interactor->GetControlKey( ) == 1 &&
192 this->GetButtonID( ) == Self::ButtonID_Left
195 this->m_Actors->SetSuperCursor( pos, this->m_Actors->GetOrientation( ) == 2 );
196 this->InvokeEvent( vtkCommand::UserEvent + 1, pos );
199 this->m_Actors->SetCursor( pos, this->m_Actors->GetOrientation( ) == 2 );
202 this->m_Actors->HideViewerActors( );
203 this->Interactor->Render( );
206 // -------------------------------------------------------------------------
207 void cpExtensions::Interaction::ImageSliceStyle::
208 OnMouseWheelForward( )
211 if( this->m_Actors.GetPointer( ) == NULL )
213 s = this->m_Actors->GetSliceNumber( );
214 s += ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
215 this->m_Actors->SetSliceNumber( s );
216 s = this->m_Actors->GetSliceNumber( );
217 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
218 this->Interactor->Render( );
219 this->OnMouseMove( );
222 // -------------------------------------------------------------------------
223 void cpExtensions::Interaction::ImageSliceStyle::
224 OnMouseWheelBackward( )
227 if( this->m_Actors.GetPointer( ) == NULL )
229 s = this->m_Actors->GetSliceNumber( );
230 s -= ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
231 this->m_Actors->SetSliceNumber( s );
232 s = this->m_Actors->GetSliceNumber( );
233 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
234 this->Interactor->Render( );
235 this->OnMouseMove( );
238 // -------------------------------------------------------------------------
239 void cpExtensions::Interaction::ImageSliceStyle::
245 // -------------------------------------------------------------------------
246 cpExtensions::Interaction::ImageSliceStyle::
250 this->SetInteractionModeToImage2D( );
251 this->m_PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
252 this->m_PropPicker->PickFromListOn( );
254 this->m_Cursor = vtkSmartPointer< TCursor >::New( );
255 this->m_Cursor->VisibilityOff( );
256 this->m_Cursor->GetProperty( 0 )->SetColor( 1, 1, 0 );
257 this->m_Cursor->GetProperty( 1 )->SetColor( 1, 1, 0 );
260 this->m_TextBuffer[ 0 ] = '\0';
261 this->m_Text = vtkSmartPointer< vtkTextActor >::New( );
262 this->m_Text->SetTextScaleModeToNone( );
263 auto textprop = this->m_Text->GetTextProperty( );
264 textprop->SetColor( 1, 1, 0 );
265 textprop->SetFontFamilyToCourier( );
266 textprop->SetFontSize( 12 );
267 textprop->BoldOff( );
268 textprop->ItalicOff( );
269 textprop->ShadowOff( );
270 textprop->SetJustificationToLeft( );
271 textprop->SetVerticalJustificationToBottom( );
272 auto coord = this->m_Text->GetPositionCoordinate( );
273 coord->SetCoordinateSystemToNormalizedViewport( );
274 coord->SetValue( 0.01, 0.02 );
275 this->m_Text->VisibilityOff( );
278 // -------------------------------------------------------------------------
279 cpExtensions::Interaction::ImageSliceStyle::
284 // -------------------------------------------------------------------------
285 bool cpExtensions::Interaction::ImageSliceStyle::
286 _PickPointOnImageActor( int idx[ 2 ], double pnt[ 3 ] )
288 // Check if data is valid
290 this->Interactor == NULL ||
291 this->CurrentRenderer == NULL ||
292 this->m_PropPicker.GetPointer( ) == NULL
296 // Find the renderer where the event has been raised
297 idx[ 0 ] = this->Interactor->GetEventPosition( )[ 0 ];
298 idx[ 1 ] = this->Interactor->GetEventPosition( )[ 1 ];
299 this->FindPokedRenderer( double( idx[ 0 ] ), double( idx[ 1 ] ) );
301 // Check if the image has changed
302 this->Interactor->GetPicker( )->
303 Pick( idx[ 0 ], idx[ 1 ], 0.0, this->CurrentRenderer );
305 vtkAbstractPropPicker::SafeDownCast( this->Interactor->GetPicker( ) );
308 TWLActor* curr_actor = dynamic_cast< TWLActor* >( picker->GetProp3D( ) );
309 if( curr_actor != this->m_WLActor.GetPointer( ) && curr_actor != NULL )
311 this->m_WLActor = curr_actor;
312 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
313 this->m_PropPicker->AddPickList( curr_actor );
315 auto props = this->CurrentRenderer->GetViewProps( );
316 this->m_LUTActor = NULL;
317 props->InitTraversal( );
319 while( ( ( prop = props->GetNextProp( ) ) != NULL ) && ( this->m_LUTActor.GetPointer( ) == NULL ) )
320 this->m_LUTActor = dynamic_cast< TLUTActor* >( prop );
322 this->m_Cursor->SetImageBounds( curr_actor->GetImage( )->GetBounds( ) );
323 this->m_Cursor->SetImageOrientation( curr_actor->GetOrientation( ) );
324 this->m_Cursor->InitTraversal( );
325 while( vtkProp* prop = this->m_Cursor->GetNextProp( ) )
326 this->CurrentRenderer->AddViewProp( prop );
327 this->CurrentRenderer->AddViewProp( this->m_Text );
330 if( this->m_WLActor.GetPointer( ) == NULL )
332 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
337 // Pick a 3D position
338 int r = this->m_PropPicker->Pick(
339 double( idx[ 0 ] ), double( idx[ 1 ] ), double( 0 ),
340 this->CurrentRenderer
344 this->m_PropPicker->GetPickPosition( pnt );
348 // -------------------------------------------------------------------------
349 void cpExtensions::Interaction::ImageSliceStyle::
350 _CorrectPosition( double pos[ 3 ], int ijk[ 3 ] )
352 if( this->m_WLActor.GetPointer( ) == NULL )
354 auto image = this->m_WLActor->GetImage( );
358 // Approximate image index
360 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
362 // Manually correct index
364 image->GetExtent( ext );
365 for( int i = 0; i < 3; ++i )
367 if( ijk[ i ] < ext[ i << 1 ] )
368 ijk[ i ] = ext[ i << 1 ];
369 if( ext[ ( i << 1 ) + 1 ] < ijk[ i ] )
370 ijk[ i ] = ext[ ( i << 1 ) + 1 ];
374 // Get real coordinates
375 int o = this->m_WLActor->GetOrientation( );
376 ijk[ o ] = this->m_WLActor->GetSliceNumber( );
377 image->GetPoint( image->ComputePointId( ijk ), pos );
380 // -------------------------------------------------------------------------
381 void cpExtensions::Interaction::ImageSliceStyle::
382 _ShowText( double pos[ 3 ] )
384 if( this->m_WLActor.GetPointer( ) == NULL )
386 auto image = this->m_WLActor->GetImage( );
391 this->_CorrectPosition( pos, ijk );
392 int o = this->m_WLActor->GetOrientation( );
394 std::stringstream buffer;
395 buffer << "Axis: " << char( 'X' + char( o ) ) << std::endl;
396 int nScl = image->GetNumberOfScalarComponents( );
398 << "Pixel: [" << ijk[ 0 ]
400 << "," << ijk[ 2 ] << "] = < "
401 << image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], 0 );
402 for( int n = 1; n < nScl; ++n )
405 << image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], n );
406 buffer << " >" << std::endl;
409 << pos[ 0 ] << ", " << pos[ 1 ] << ", " << pos[ 2 ]
411 cpExtensions_SPRINTF( this->m_TextBuffer, 1024, buffer.str( ).c_str( ) );
412 this->m_Text->SetInput( this->m_TextBuffer );
413 this->m_Text->VisibilityOn( );
414 this->m_Text->Modified( );