#include <cpPlugins/Extensions/Visualization/ImageInteractorStyle.h>
+#include <cmath>
#include <ctime>
#include <vtkAnnotatedCubeActor.h>
#include <vtkAxesActor.h>
#include <vtkCallbackCommand.h>
#include <vtkCamera.h>
+#include <vtkCellArray.h>
#include <vtkCommand.h>
+#include <vtkMatrix4x4.h>
#include <vtkPropAssembly.h>
#include <vtkProperty.h>
#include <vtkRendererCollection.h>
// -------------------------------------------------------------------------
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::
if( interactor == NULL )
return;
- // TODO: interactor->SetPicker( this->PropPicker );
-
// Get camera, avoiding segfaults
vtkRenderer* ren =
interactor->GetRenderWindow( )->GetRenderers( )->GetFirstRenderer( );
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( )
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 )
}
else if( this->Interactor->GetControlKey( ) )
{
+ this->StartRadiusMoving( );
}
else if( this->Interactor->GetShiftKey( ) )
{
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
}
// -------------------------------------------------------------------------
{
if( this->CursorMoving )
return;
+ this->_PickPosition( this->Cursor );
this->CursorMoving = true;
}
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( )
Mode( Self::NavigationMode ),
m_SliceActors( NULL ),
m_MPRActors( NULL ),
- CursorMoving( false )
+ CursorMoving( false ),
+ RadiusMoving( false )
{
// Orientation marks
vtkSmartPointer< vtkAnnotatedCubeActor > cube =
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( );
}
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 );
}
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$
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
public:
vtkTypeMacro( ImageInteractorStyle, vtkInteractorStyleImage );
+ cpPlugins_ImageInteractorStyle_ObserverMacro( DoubleClick );
+ cpPlugins_ImageInteractorStyle_ObserverMacro( Cursor );
+ cpPlugins_ImageInteractorStyle_ObserverMacro( Radius );
+
public:
static Self* New( );
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.
// New events
virtual void StartCursorMoving( );
virtual void EndCursorMoving( );
+ virtual void StartRadiusMoving( );
+ virtual void EndRadiusMoving( );
protected:
ImageInteractorStyle( );
void _RenderAssociateInteractors( );
bool _PickPosition( double pos[ 3 ] );
void _UpdateCursor( );
+ void _UpdateRadius( );
private:
// Purposely not implemented
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;
};