1 #include <cpExtensions/Utility.h>
2 #include <cpExtensions/Interaction/ImageSliceStyle.h>
3 #include <cpExtensions/Visualization/CursorActors.h>
4 #include <cpExtensions/Visualization/WindowLevelImageActor.h>
5 #include <vtkAssemblyPath.h>
6 #include <vtkImageData.h>
7 #include <vtkImageSlice.h>
8 #include <vtkProperty.h>
9 #include <vtkPropCollection.h>
10 #include <vtkPropPicker.h>
11 #include <vtkRenderer.h>
12 #include <vtkTextActor.h>
13 #include <vtkTextProperty.h>
17 #include <cpExtensions/Visualization/ImageViewerActors.h>
20 // -------------------------------------------------------------------------
21 cpExtensions::Interaction::ImageSliceStyle::
22 Self* cpExtensions::Interaction::ImageSliceStyle::
25 return( new Self( ) );
28 // -------------------------------------------------------------------------
29 int cpExtensions::Interaction::ImageSliceStyle::
30 GetSliceNumber( ) const
32 if( this->m_WLActor.GetPointer( ) != NULL )
33 return( this->m_WLActor->GetSliceNumber( ) );
38 // -------------------------------------------------------------------------
39 int cpExtensions::Interaction::ImageSliceStyle::
40 GetOrientation( ) const
42 if( this->m_WLActor.GetPointer( ) != NULL )
43 return( this->m_WLActor->GetOrientation( ) );
48 // -------------------------------------------------------------------------
49 void cpExtensions::Interaction::ImageSliceStyle::
52 static bool cursor_visible = false;
56 if( this->_PickPointOnImageActor( idx, pnt ) )
58 this->m_Cursor->SetCursor( pnt, false );
59 this->_ShowText( pnt );
62 this->m_Cursor->VisibilityOn( );
63 this->m_Text->VisibilityOn( );
64 cursor_visible = true;
67 this->Interactor->Render( );
73 this->m_Cursor->VisibilityOff( );
74 this->m_Text->VisibilityOff( );
75 cursor_visible = false;
76 this->Interactor->Render( );
82 this->Overclass::OnMouseMove( );
85 // -------------------------------------------------------------------------
86 void cpExtensions::Interaction::ImageSliceStyle::
87 OnMouseWheelForward( )
90 if( this->m_WLActor.GetPointer( ) == NULL )
92 s = this->m_WLActor->GetSliceNumber( );
93 s += ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
94 this->m_WLActor->SetSliceNumber( s );
95 s = this->m_WLActor->GetSliceNumber( );
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 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
113 this->Interactor->Render( );
114 this->OnMouseMove( );
117 // -------------------------------------------------------------------------
118 void cpExtensions::Interaction::ImageSliceStyle::
121 switch( this->Interactor->GetKeyCode( ) )
125 this->FindPokedRenderer(
126 this->Interactor->GetEventPosition( )[ 0 ],
127 this->Interactor->GetEventPosition( )[ 1 ]
129 this->CurrentRenderer->ResetCamera( );
130 this->Interactor->Render( );
140 cpExtensions::Visualization::ImageViewerActors*
141 cpExtensions::Interaction::ImageSliceStyle::
144 return( this->m_Actors );
147 // -------------------------------------------------------------------------
148 const cpExtensions::Visualization::ImageViewerActors*
149 cpExtensions::Interaction::ImageSliceStyle::
152 return( this->m_Actors );
155 // -------------------------------------------------------------------------
156 void cpExtensions::Interaction::ImageSliceStyle::
157 SetActors( cpExtensions::Visualization::ImageViewerActors* actors )
159 this->m_Actors = actors;
162 this->m_PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
163 this->m_PropPicker->PickFromListOn( );
164 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
166 AddPickList( this->m_Actors->GetWindowLevelImageActor( ) );
169 this->m_PropPicker = NULL;
172 // -------------------------------------------------------------------------
173 void cpExtensions::Interaction::ImageSliceStyle::
176 this->Superclass::OnMouseMove( );
177 if( this->m_Actors.GetPointer( ) == NULL )
182 static double pos[ 3 ];
183 if( this->_PickPosition( idx, pos ) )
186 this->Interactor->GetControlKey( ) == 1 &&
187 this->GetButtonID( ) == Self::ButtonID_Left
190 this->m_Actors->SetSuperCursor( pos, this->m_Actors->GetOrientation( ) == 2 );
191 this->InvokeEvent( vtkCommand::UserEvent + 1, pos );
194 this->m_Actors->SetCursor( pos, this->m_Actors->GetOrientation( ) == 2 );
197 this->m_Actors->HideViewerActors( );
198 this->Interactor->Render( );
201 // -------------------------------------------------------------------------
202 void cpExtensions::Interaction::ImageSliceStyle::
203 OnMouseWheelForward( )
206 if( this->m_Actors.GetPointer( ) == NULL )
208 s = this->m_Actors->GetSliceNumber( );
209 s += ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
210 this->m_Actors->SetSliceNumber( s );
211 s = this->m_Actors->GetSliceNumber( );
212 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
213 this->Interactor->Render( );
214 this->OnMouseMove( );
217 // -------------------------------------------------------------------------
218 void cpExtensions::Interaction::ImageSliceStyle::
219 OnMouseWheelBackward( )
222 if( this->m_Actors.GetPointer( ) == NULL )
224 s = this->m_Actors->GetSliceNumber( );
225 s -= ( this->Interactor->GetShiftKey( ) == 1 )? 10: 1;
226 this->m_Actors->SetSliceNumber( s );
227 s = this->m_Actors->GetSliceNumber( );
228 this->InvokeEvent( vtkCommand::UserEvent + 2, &s );
229 this->Interactor->Render( );
230 this->OnMouseMove( );
233 // -------------------------------------------------------------------------
234 void cpExtensions::Interaction::ImageSliceStyle::
240 // -------------------------------------------------------------------------
241 cpExtensions::Interaction::ImageSliceStyle::
245 this->SetInteractionModeToImage2D( );
246 this->m_PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
247 this->m_PropPicker->PickFromListOn( );
249 this->m_Cursor = vtkSmartPointer< TCursor >::New( );
250 this->m_Cursor->VisibilityOff( );
251 this->m_Cursor->GetProperty( 0 )->SetColor( 1, 1, 0 );
252 this->m_Cursor->GetProperty( 1 )->SetColor( 1, 1, 0 );
255 this->m_TextBuffer[ 0 ] = '\0';
256 this->m_Text = vtkSmartPointer< vtkTextActor >::New( );
257 this->m_Text->SetTextScaleModeToNone( );
258 auto textprop = this->m_Text->GetTextProperty( );
259 textprop->SetColor( 1, 1, 0 );
260 textprop->SetFontFamilyToCourier( );
261 textprop->SetFontSize( 12 );
262 textprop->BoldOff( );
263 textprop->ItalicOff( );
264 textprop->ShadowOff( );
265 textprop->SetJustificationToLeft( );
266 textprop->SetVerticalJustificationToBottom( );
267 auto coord = this->m_Text->GetPositionCoordinate( );
268 coord->SetCoordinateSystemToNormalizedViewport( );
269 coord->SetValue( 0.01, 0.02 );
270 this->m_Text->VisibilityOff( );
273 // -------------------------------------------------------------------------
274 cpExtensions::Interaction::ImageSliceStyle::
279 // -------------------------------------------------------------------------
280 bool cpExtensions::Interaction::ImageSliceStyle::
281 _PickPointOnImageActor( int idx[ 2 ], double pnt[ 3 ] )
283 // Check if data is valid
285 this->Interactor == NULL ||
286 this->CurrentRenderer == NULL ||
287 this->m_PropPicker.GetPointer( ) == NULL
291 // Find the renderer where the event has been raised
292 idx[ 0 ] = this->Interactor->GetEventPosition( )[ 0 ];
293 idx[ 1 ] = this->Interactor->GetEventPosition( )[ 1 ];
294 this->FindPokedRenderer( double( idx[ 0 ] ), double( idx[ 1 ] ) );
296 // Check if the image has changed
297 this->Interactor->GetPicker( )->
298 Pick( idx[ 0 ], idx[ 1 ], 0.0, this->CurrentRenderer );
300 vtkAbstractPropPicker::SafeDownCast( this->Interactor->GetPicker( ) );
303 TWLActor* curr_actor = dynamic_cast< TWLActor* >( picker->GetProp3D( ) );
304 if( curr_actor != this->m_WLActor.GetPointer( ) && curr_actor != NULL )
306 this->m_WLActor = curr_actor;
307 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
308 this->m_PropPicker->AddPickList( curr_actor );
310 this->m_Cursor->SetImageBounds( curr_actor->GetImage( )->GetBounds( ) );
311 this->m_Cursor->SetImageOrientation( curr_actor->GetOrientation( ) );
312 this->m_Cursor->InitTraversal( );
313 while( vtkProp* prop = this->m_Cursor->GetNextProp( ) )
314 this->CurrentRenderer->AddViewProp( prop );
315 this->CurrentRenderer->AddViewProp( this->m_Text );
318 if( this->m_WLActor.GetPointer( ) == NULL )
320 this->m_PropPicker->GetPickList( )->RemoveAllItems( );
325 // Pick a 3D position
326 int r = this->m_PropPicker->Pick(
327 double( idx[ 0 ] ), double( idx[ 1 ] ), double( 0 ),
328 this->CurrentRenderer
332 this->m_PropPicker->GetPickPosition( pnt );
336 // -------------------------------------------------------------------------
337 void cpExtensions::Interaction::ImageSliceStyle::
338 _CorrectPosition( double pos[ 3 ], int ijk[ 3 ] )
340 if( this->m_WLActor.GetPointer( ) == NULL )
342 auto image = this->m_WLActor->GetImage( );
346 // Approximate image index
348 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
350 // Manually correct index
352 image->GetExtent( ext );
353 for( int i = 0; i < 3; ++i )
355 if( ijk[ i ] < ext[ i << 1 ] )
356 ijk[ i ] = ext[ i << 1 ];
357 if( ext[ ( i << 1 ) + 1 ] < ijk[ i ] )
358 ijk[ i ] = ext[ ( i << 1 ) + 1 ];
362 // Get real coordinates
363 int o = this->m_WLActor->GetOrientation( );
364 ijk[ o ] = this->m_WLActor->GetSliceNumber( );
365 image->GetPoint( image->ComputePointId( ijk ), pos );
368 // -------------------------------------------------------------------------
369 void cpExtensions::Interaction::ImageSliceStyle::
370 _ShowText( double pos[ 3 ] )
372 if( this->m_WLActor.GetPointer( ) == NULL )
374 auto image = this->m_WLActor->GetImage( );
379 this->_CorrectPosition( pos, ijk );
380 int o = this->m_WLActor->GetOrientation( );
382 std::stringstream buffer;
383 buffer << "Axis: " << char( 'X' + char( o ) ) << std::endl;
384 int nScl = image->GetNumberOfScalarComponents( );
386 << "Pixel: [" << ijk[ 0 ]
388 << "," << ijk[ 2 ] << "] = < "
389 << image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], 0 );
390 for( int n = 1; n < nScl; ++n )
393 << image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], n );
394 buffer << " >" << std::endl;
397 << pos[ 0 ] << ", " << pos[ 1 ] << ", " << pos[ 2 ]
399 cpExtensions_SPRINTF( this->m_TextBuffer, 1024, buffer.str( ).c_str( ) );
400 this->m_Text->SetInput( this->m_TextBuffer );
401 this->m_Text->VisibilityOn( );
402 this->m_Text->Modified( );