From 47f20ae9bdea419f3b2526dc6f0d3bfff85b0065 Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Wed, 17 Dec 2014 16:11:53 +0100 Subject: [PATCH] ROI interaction added --- .../Visualization/ImageInteractorStyle.cxx | 189 ++++++++++++++---- .../Visualization/ImageInteractorStyle.h | 32 ++- .../Visualization/ImageSliceActors.cxx | 14 ++ .../Visualization/ImageSliceActors.h | 3 + .../Visualization/MPRWithDifferentWindows.cxx | 27 --- .../Visualization/MPRWithDifferentWindows.h | 29 ++- 6 files changed, 219 insertions(+), 75 deletions(-) diff --git a/lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.cxx b/lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.cxx index 67a271f..1ff0739 100644 --- a/lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.cxx +++ b/lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.cxx @@ -1,12 +1,15 @@ #include +#include #include #include #include #include #include +#include #include +#include #include #include #include @@ -18,7 +21,11 @@ // ------------------------------------------------------------------------- const int cpPlugins::Extensions::Visualization:: -ImageInteractorStyle::DoubleClickEvent = vtkCommand::UserEvent + 1; +ImageInteractorStyle::CursorEvent = vtkCommand::UserEvent + 1; +const int cpPlugins::Extensions::Visualization:: +ImageInteractorStyle::RadiusEvent = vtkCommand::UserEvent + 2; +const int cpPlugins::Extensions::Visualization:: +ImageInteractorStyle::DoubleClickEvent = vtkCommand::UserEvent + 3; // ------------------------------------------------------------------------- cpPlugins::Extensions::Visualization::ImageInteractorStyle:: @@ -75,8 +82,6 @@ SetInteractor( vtkRenderWindowInteractor* interactor, const int& axis ) if( interactor == NULL ) return; - // TODO: interactor->SetPicker( this->PropPicker ); - // Get camera, avoiding segfaults vtkRenderer* ren = interactor->GetRenderWindow( )->GetRenderers( )->GetFirstRenderer( ); @@ -112,34 +117,6 @@ SetInteractor( vtkRenderWindowInteractor* interactor, const int& axis ) this->OrientationWidget->InteractiveOff( ); } -// ------------------------------------------------------------------------- -unsigned long cpPlugins::Extensions::Visualization::ImageInteractorStyle:: -AddDoubleClickObserver( vtkCommand* observer ) -{ - return( this->AddObserver( Self::DoubleClickEvent, observer ) ); -} - -// ------------------------------------------------------------------------- -void cpPlugins::Extensions::Visualization::ImageInteractorStyle:: -RemoveDoubleClickObserver( unsigned long tag ) -{ - this->RemoveObserver( tag ); -} - -// ------------------------------------------------------------------------- -void cpPlugins::Extensions::Visualization::ImageInteractorStyle:: -RemoveDoubleClickObserver( vtkCommand* observer ) -{ - this->RemoveObserver( observer ); -} - -// ------------------------------------------------------------------------- -void cpPlugins::Extensions::Visualization::ImageInteractorStyle:: -RemoveDoubleClickObservers( ) -{ - this->RemoveObservers( Self::DoubleClickEvent ); -} - // ------------------------------------------------------------------------- void cpPlugins::Extensions::Visualization::ImageInteractorStyle:: OnMouseMove( ) @@ -147,20 +124,30 @@ OnMouseMove( ) if( this->m_MPRActors == NULL ) return; - double pos[ 3 ]; if( this->CursorMoving ) { - bool picked = this->_PickPosition( pos ); + bool picked = this->_PickPosition( this->Cursor ); if( picked ) { for( int i = 0; i < 3; ++i ) if( this->m_SliceActors->GetAxis( ) != i ) - this->m_MPRActors->SetSlice( i, pos[ i ] ); + this->m_MPRActors->SetSlice( i, this->Cursor[ i ] ); + this->InvokeEvent( Self::CursorEvent, this->Cursor ); this->Interactor->Render( ); this->_RenderAssociateInteractors( ); } // fi } + else if( this->RadiusMoving ) + { + bool picked = this->_PickPosition( this->Radius ); + if( picked ) + { + this->InvokeEvent( Self::RadiusEvent, this->Radius ); + this->_UpdateRadius( ); + + } // fi + } else { switch( this->State ) @@ -241,6 +228,7 @@ OnMiddleButtonDown( ) } else if( this->Interactor->GetControlKey( ) ) { + this->StartRadiusMoving( ); } else if( this->Interactor->GetShiftKey( ) ) { @@ -253,12 +241,22 @@ OnMiddleButtonDown( ) void cpPlugins::Extensions::Visualization::ImageInteractorStyle:: OnMiddleButtonUp( ) { - switch( this->State ) + if( this->RadiusMoving ) { - case VTKIS_PAN: - this->EndPan( ); - break; - } // hctiws + this->EndRadiusMoving( ); + if( this->Interactor ) + this->ReleaseFocus( ); + } + else + { + switch( this->State ) + { + case VTKIS_PAN: + this->EndPan( ); + break; + } // hctiws + + } // fi } // ------------------------------------------------------------------------- @@ -461,6 +459,7 @@ StartCursorMoving( ) { if( this->CursorMoving ) return; + this->_PickPosition( this->Cursor ); this->CursorMoving = true; } @@ -473,6 +472,28 @@ EndCursorMoving( ) this->CursorMoving = false; } +// ------------------------------------------------------------------------- +void cpPlugins::Extensions::Visualization::ImageInteractorStyle:: +StartRadiusMoving( ) +{ + if( this->RadiusMoving ) + return; + this->_PickPosition( this->Radius ); + this->RadiusMoving = true; + this->_UpdateRadius( ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Extensions::Visualization::ImageInteractorStyle:: +EndRadiusMoving( ) +{ + if( !( this->RadiusMoving ) ) + return; + this->RadiusMoving = false; + this->_UpdateRadius( ); + this->InvokeEvent( Self::RadiusEvent, NULL ); +} + // ------------------------------------------------------------------------- cpPlugins::Extensions::Visualization::ImageInteractorStyle:: ImageInteractorStyle( ) @@ -480,7 +501,8 @@ ImageInteractorStyle( ) Mode( Self::NavigationMode ), m_SliceActors( NULL ), m_MPRActors( NULL ), - CursorMoving( false ) + CursorMoving( false ), + RadiusMoving( false ) { // Orientation marks vtkSmartPointer< vtkAnnotatedCubeActor > cube = @@ -520,6 +542,36 @@ ImageInteractorStyle( ) this->OrientationWidget->SetOrientationMarker( actors ); this->OrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 ); + // Circle + unsigned long circle_samples = 1000; + this->Circle = vtkSmartPointer< vtkPolyData >::New( ); + + vtkSmartPointer< vtkPoints > circle_points = + vtkSmartPointer< vtkPoints >::New( ); + vtkSmartPointer< vtkCellArray > circle_lines = + vtkSmartPointer< vtkCellArray >::New( ); + for( unsigned long s = 0; s < circle_samples; ++s ) + { + double t = double( 6.2832 ) * double( s ) / double( circle_samples ); + circle_points->InsertNextPoint( + std::cos( t ), std::sin( t ), double( 0 ) + ); + + circle_lines->InsertNextCell( 2 ); + circle_lines->InsertCellPoint( s ); + circle_lines->InsertCellPoint( ( s + 1 ) % circle_samples ); + + } // rof + this->Circle->SetPoints( circle_points ); + this->Circle->SetLines( circle_lines ); + + this->CircleMapper = vtkSmartPointer< vtkPolyDataMapper >::New( ); + this->CircleMapper->SetInputData( this->Circle ); + this->CircleActor = vtkSmartPointer< vtkActor >::New( ); + this->CircleActor->SetMapper( this->CircleMapper ); + this->CircleActor->GetProperty( )->SetColor( 1, 0, 1 ); + this->CircleActor->GetProperty( )->SetLineWidth( 2 ); + this->PropPicker = vtkSmartPointer< vtkPropPicker >::New( ); this->PropPicker->PickFromListOn( ); } @@ -555,6 +607,11 @@ _PickPosition( double pos[ 3 ] ) if( success == 0 ) return( false ); this->PropPicker->GetPickPosition( pos ); + + int axis = this->m_SliceActors->GetAxis( ); + double* bounds = this->m_SliceActors->GetDisplayBounds( ); + pos[ axis ] = bounds[ axis << 1 ]; + return( true ); } @@ -565,4 +622,56 @@ _UpdateCursor( ) std::cout << "upcur" << std::endl; } +// ------------------------------------------------------------------------- +void cpPlugins::Extensions::Visualization::ImageInteractorStyle:: +_UpdateRadius( ) +{ + vtkRenderer* ren = + this->Interactor->GetRenderWindow( )-> + GetRenderers( )->GetFirstRenderer( ); + if( ren == NULL ) + return; + vtkCamera* cam = ren->GetActiveCamera( ); + if( cam == NULL ) + return; + + if( this->RadiusMoving ) + { + double x = this->Cursor[ 0 ] - this->Radius[ 0 ]; + double y = this->Cursor[ 1 ] - this->Radius[ 1 ]; + double z = this->Cursor[ 2 ] - this->Radius[ 2 ]; + double r = std::sqrt( ( x * x ) + ( y * y ) + ( z * z ) ); + + vtkMatrix4x4* cam_matrix = cam->GetModelViewTransformMatrix( ); + vtkSmartPointer< vtkMatrix4x4 > circle_matrix = + this->CircleActor->GetUserMatrix( ); + if( circle_matrix.GetPointer( ) == NULL ) + { + circle_matrix = vtkSmartPointer< vtkMatrix4x4 >::New( ); + this->CircleActor->SetUserMatrix( circle_matrix ); + + } // fi + for( int i = 0; i < 4; ++i ) + { + for( int j = 0; j < 4; ++j ) + { + double v = cam_matrix->GetElement( i, j ); + if( i < 3 && j == 3 ) + v = this->Cursor[ i ]; + if( i < 3 && j < 3 ) + v *= r; + circle_matrix->SetElement( i, j, v ); + + } // rof + + } // rof + this->CircleActor->Modified( ); + ren->AddActor( this->CircleActor ); + } + else + ren->RemoveActor( this->CircleActor ); + + this->Interactor->Render( ); +} + // eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.h b/lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.h index f2909e2..3bde551 100644 --- a/lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.h +++ b/lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.h @@ -16,6 +16,17 @@ class vtkImageData; */ +// ------------------------------------------------------------------------- +#define cpPlugins_ImageInteractorStyle_ObserverMacro( e ) \ + inline unsigned long Add##e##Observer( vtkCommand* observer ) \ + { return( this->AddObserver( Self::e##Event, observer ) ); } \ + inline void Remove##e##Observer( unsigned long tag ) \ + { this->RemoveObserver( tag ); } \ + inline void Remove##e##Observer( vtkCommand* observer ) \ + { this->RemoveObserver( observer ); } \ + inline void Remove##e##Observers( ) \ + { this->RemoveObservers( Self::e##Event ); } + namespace cpPlugins { namespace Extensions @@ -42,6 +53,10 @@ namespace cpPlugins public: vtkTypeMacro( ImageInteractorStyle, vtkInteractorStyleImage ); + cpPlugins_ImageInteractorStyle_ObserverMacro( DoubleClick ); + cpPlugins_ImageInteractorStyle_ObserverMacro( Cursor ); + cpPlugins_ImageInteractorStyle_ObserverMacro( Radius ); + public: static Self* New( ); @@ -57,11 +72,6 @@ namespace cpPlugins vtkRenderWindowInteractor* interactor, const int& axis ); - unsigned long AddDoubleClickObserver( vtkCommand* observer ); - void RemoveDoubleClickObserver( unsigned long tag ); - void RemoveDoubleClickObserver( vtkCommand* observer ); - void RemoveDoubleClickObservers( ); - // Description: // Event bindings controlling the effects of pressing mouse buttons // or moving the mouse. @@ -103,6 +113,8 @@ namespace cpPlugins // New events virtual void StartCursorMoving( ); virtual void EndCursorMoving( ); + virtual void StartRadiusMoving( ); + virtual void EndRadiusMoving( ); protected: ImageInteractorStyle( ); @@ -111,6 +123,7 @@ namespace cpPlugins void _RenderAssociateInteractors( ); bool _PickPosition( double pos[ 3 ] ); void _UpdateCursor( ); + void _UpdateRadius( ); private: // Purposely not implemented @@ -129,8 +142,17 @@ namespace cpPlugins std::vector< vtkRenderWindowInteractor* > AssociatedInteractors; bool CursorMoving; + double Cursor[ 3 ]; + + bool RadiusMoving; + double Radius[ 3 ]; + vtkSmartPointer< vtkPolyData > Circle; + vtkSmartPointer< vtkPolyDataMapper > CircleMapper; + vtkSmartPointer< vtkActor > CircleActor; public: + static const int CursorEvent; + static const int RadiusEvent; static const int DoubleClickEvent; }; diff --git a/lib/cpPlugins/Extensions/Visualization/ImageSliceActors.cxx b/lib/cpPlugins/Extensions/Visualization/ImageSliceActors.cxx index 810cbf0..0ec6bb8 100644 --- a/lib/cpPlugins/Extensions/Visualization/ImageSliceActors.cxx +++ b/lib/cpPlugins/Extensions/Visualization/ImageSliceActors.cxx @@ -46,6 +46,20 @@ SetSegmentationConnection( vtkAlgorithmOutput* aout ) this->Modified( ); } +// ------------------------------------------------------------------------- +double* cpPlugins::Extensions::Visualization::ImageSliceActors:: +GetDisplayBounds( ) const +{ + return( this->ImageActor->GetDisplayBounds( ) ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Extensions::Visualization::ImageSliceActors:: +GetDisplayBounds( double bounds[ 6 ] ) const +{ + this->ImageActor->GetDisplayBounds( bounds ); +} + // ------------------------------------------------------------------------- int cpPlugins::Extensions::Visualization::ImageSliceActors:: GetAxis( ) const diff --git a/lib/cpPlugins/Extensions/Visualization/ImageSliceActors.h b/lib/cpPlugins/Extensions/Visualization/ImageSliceActors.h index ed1faff..c086937 100644 --- a/lib/cpPlugins/Extensions/Visualization/ImageSliceActors.h +++ b/lib/cpPlugins/Extensions/Visualization/ImageSliceActors.h @@ -55,6 +55,9 @@ namespace cpPlugins void SetInputConnection( vtkAlgorithmOutput* aout, int axis ); void SetSegmentationConnection( vtkAlgorithmOutput* aout ); + double* GetDisplayBounds( ) const; + void GetDisplayBounds( double bounds[ 6 ] ) const; + int GetAxis( ) const; int GetSliceNumber( ) const; int GetSliceNumberMinValue( ) const; diff --git a/lib/cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.cxx b/lib/cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.cxx index 6a7851a..e271631 100644 --- a/lib/cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.cxx +++ b/lib/cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.cxx @@ -72,33 +72,6 @@ cpPlugins::Extensions::Visualization::MPRWithDifferentWindows:: { } -// ------------------------------------------------------------------------- -void cpPlugins::Extensions::Visualization::MPRWithDifferentWindows:: -AddDoubleClickObserver( vtkCommand* observer ) -{ - for( int i = 0; i < 3; ++i ) - if( this->m_Styles[ i ].GetPointer( ) != NULL ) - this->m_Styles[ i ]->AddDoubleClickObserver( observer ); -} - -// ------------------------------------------------------------------------- -void cpPlugins::Extensions::Visualization::MPRWithDifferentWindows:: -RemoveDoubleClickObserver( vtkCommand* observer ) -{ - for( int i = 0; i < 3; ++i ) - if( this->m_Styles[ i ].GetPointer( ) != NULL ) - this->m_Styles[ i ]->RemoveDoubleClickObserver( observer ); -} - -// ------------------------------------------------------------------------- -void cpPlugins::Extensions::Visualization::MPRWithDifferentWindows:: -RemoveDoubleClickObservers( ) -{ - for( int i = 0; i < 3; ++i ) - if( this->m_Styles[ i ].GetPointer( ) != NULL ) - this->m_Styles[ i ]->RemoveDoubleClickObservers( ); -} - // ------------------------------------------------------------------------- void cpPlugins::Extensions::Visualization::MPRWithDifferentWindows:: SetImage( vtkImageData* image ) diff --git a/lib/cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.h b/lib/cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.h index 6ac17e8..b0f8c40 100644 --- a/lib/cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.h +++ b/lib/cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.h @@ -9,6 +9,27 @@ #include #include +// ------------------------------------------------------------------------- +#define cpPlugins_MPRWithDifferentWindows_ObserverMacro( e ) \ +inline void Add##e##Observer( vtkCommand* observer ) \ +{ \ + for( int i = 0; i < 3; ++i ) \ + if( this->m_Styles[ i ].GetPointer( ) != NULL ) \ + this->m_Styles[ i ]->Add##e##Observer( observer ); \ +} \ +inline void Remove##e##Observer( vtkCommand* observer ) \ +{ \ + for( int i = 0; i < 3; ++i ) \ + if( this->m_Styles[ i ].GetPointer( ) != NULL ) \ + this->m_Styles[ i ]->Remove##e##Observer( observer ); \ +} \ +inline void Remove##e##Observers( ) \ +{ \ + for( int i = 0; i < 3; ++i ) \ + if( this->m_Styles[ i ].GetPointer( ) != NULL ) \ + this->m_Styles[ i ]->Remove##e##Observers( ); \ +} + namespace cpPlugins { namespace Extensions @@ -25,6 +46,11 @@ namespace cpPlugins typedef cpPlugins::Extensions::Visualization:: ImageInteractorStyle TStyle; + public: + cpPlugins_MPRWithDifferentWindows_ObserverMacro( DoubleClick ); + cpPlugins_MPRWithDifferentWindows_ObserverMacro( Cursor ); + cpPlugins_MPRWithDifferentWindows_ObserverMacro( Radius ); + public: MPRWithDifferentWindows( vtkRenderWindow* xWin = NULL, @@ -34,9 +60,6 @@ namespace cpPlugins ); virtual ~MPRWithDifferentWindows( ); - void AddDoubleClickObserver( vtkCommand* observer ); - void RemoveDoubleClickObserver( vtkCommand* observer ); - void RemoveDoubleClickObservers( ); void SetImage( vtkImageData* image ); void SetSegmentation( vtkImageData* image ); -- 2.47.1