Affine interaction with objects in 3D windows. More...
#include <mitkSurfaceDeformationInteractor3D.h>
Public Types | |
typedef SurfaceDeformationInteractor3D | Self |
typedef Interactor | Superclass |
typedef itk::SmartPointer< Self > | Pointer |
typedef itk::SmartPointer < const Self > | ConstPointer |
Public Member Functions | |
virtual const char * | GetClassName () const |
void | SetPrecision (ScalarType precision) |
Sets the amount of precision. | |
virtual float | CanHandleEvent (StateEvent const *stateEvent) const |
calculates how good the data, this statemachine handles, is hit by the event. | |
Static Public Member Functions | |
static Pointer | New (const char *_arga, DataNode *_argb, int _argc) |
static Pointer | New (const char *_arga, DataNode *_argb) |
NewMacro with two parameters for calling itk::Lightobject::New(..) method. | |
Protected Types | |
enum | { COLORIZATION_GAUSS, COLORIZATION_CONSTANT } |
Protected Member Functions | |
SurfaceDeformationInteractor3D (const char *type, DataNode *dataNode, int n=-1) | |
Constructor with Param n for limited Set of Points. | |
virtual | ~SurfaceDeformationInteractor3D () |
Default Destructor. | |
virtual bool | ExecuteAction (Action *action, mitk::StateEvent const *stateEvent) |
Method called in HandleEvent after Statechange. | |
bool | ColorizeSurface (vtkPolyData *polyData, const Point3D &pickedPoint, int mode, double scalar=0.0) |
Affine interaction with objects in 3D windows.
NOTE: The interaction mechanism is similar to that of vtkPlaneWidget
Definition at line 43 of file mitkSurfaceDeformationInteractor3D.h.
typedef itk::SmartPointer<const Self> mitk::SurfaceDeformationInteractor3D::ConstPointer |
Reimplemented from mitk::Interactor.
Definition at line 46 of file mitkSurfaceDeformationInteractor3D.h.
typedef itk::SmartPointer<Self> mitk::SurfaceDeformationInteractor3D::Pointer |
Reimplemented from mitk::Interactor.
Definition at line 46 of file mitkSurfaceDeformationInteractor3D.h.
Reimplemented from mitk::Interactor.
Definition at line 46 of file mitkSurfaceDeformationInteractor3D.h.
Reimplemented from mitk::Interactor.
Definition at line 46 of file mitkSurfaceDeformationInteractor3D.h.
anonymous enum [protected] |
Definition at line 79 of file mitkSurfaceDeformationInteractor3D.h.
mitk::SurfaceDeformationInteractor3D::SurfaceDeformationInteractor3D | ( | const char * | type, |
DataNode * | dataNode, | ||
int | n = -1 |
||
) | [protected] |
Constructor with Param n for limited Set of Points.
if no n is set, then the number of points is unlimited*
Definition at line 50 of file mitkSurfaceDeformationInteractor3D.cpp.
References New().
: Interactor( type, dataNode ), m_Precision( 6.5 ), m_PickedSurfaceNode( NULL ), m_PickedSurface( NULL ), m_GaussSigma( 30.0 ) { m_OriginalPolyData = vtkPolyData::New(); // Initialize vector arithmetic m_ObjectNormal[0] = 0.0; m_ObjectNormal[1] = 0.0; m_ObjectNormal[2] = 1.0; }
mitk::SurfaceDeformationInteractor3D::~SurfaceDeformationInteractor3D | ( | ) | [protected, virtual] |
Default Destructor.
Definition at line 65 of file mitkSurfaceDeformationInteractor3D.cpp.
{ m_OriginalPolyData->Delete(); }
float mitk::SurfaceDeformationInteractor3D::CanHandleEvent | ( | StateEvent const * | stateEvent ) | const [virtual] |
calculates how good the data, this statemachine handles, is hit by the event.
overwritten, cause we don't look at the boundingbox, we look at each point
Reimplemented from mitk::Interactor.
Definition at line 77 of file mitkSurfaceDeformationInteractor3D.cpp.
References mitk::StateEvent::GetEvent(), and mitk::StateEvent::GetId().
{ float returnValue = 0.5; // If it is a key event that can be handled in the current state, // then return 0.5 mitk::DisplayPositionEvent const *disPosEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent()); // Key event handling: if (disPosEvent == NULL) { // Check if the current state has a transition waiting for that key event. if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL) { return 0.5; } else { return 0.0; } } //on MouseMove do nothing! //if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove) //{ // return 0.0; //} //if the event can be understood and if there is a transition waiting for that event if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL) { returnValue = 0.5;//it can be understood } //int timeStep = disPosEvent->GetSender()->GetTimeStep(); //mitk::CurveModel *curveModel = dynamic_cast<mitk::CurveModel *>( // m_DataNode->GetData() ); //if ( curveModel != NULL ) //{ // // Get the Geometry2D of the window the user interacts with (for 2D point // // projection) // mitk::BaseRenderer *renderer = stateEvent->GetEvent()->GetSender(); // const Geometry2D *projectionPlane = renderer->GetCurrentWorldGeometry2D(); // // For reading on the points, Ids etc // //mitk::CurveModel::PointSetType *pointSet = curveModel->GetPointSet( timeStep ); // //if ( pointSet == NULL ) // //{ // // return 0.0; // //} //} return returnValue; }
bool mitk::SurfaceDeformationInteractor3D::ColorizeSurface | ( | vtkPolyData * | polyData, |
const Point3D & | pickedPoint, | ||
int | mode, | ||
double | scalar = 0.0 |
||
) | [protected] |
Definition at line 442 of file mitkSurfaceDeformationInteractor3D.cpp.
References QuadProgPP::exp(), and QuadProgPP::t().
{ if ( polyData == NULL ) { return false; } vtkPoints *points = polyData->GetPoints(); vtkPointData *pointData = polyData->GetPointData(); if ( pointData == NULL ) { return false; } vtkDataArray *scalars = pointData->GetScalars(); if ( scalars == NULL ) { return false; } if ( mode == COLORIZATION_GAUSS ) { // Get picked point and transform into local coordinates mitk::Point3D localPickedPoint; m_Geometry->WorldToIndex( pickedPoint, localPickedPoint ); mitk::Vector3D v1 = localPickedPoint.GetVectorFromOrigin(); double denom = m_GaussSigma * m_GaussSigma * 2; for ( unsigned int i = 0; i < points->GetNumberOfPoints(); ++i ) { // Get original point vtkFloatingPointType *point = points->GetPoint( i ); mitk::Vector3D v0; v0[0] = point[0]; v0[1] = point[1]; v0[2] = point[2]; // Calculate distance of this point from line through picked point double d = itk::CrossProduct( m_ObjectNormal, (v1 - v0) ).GetNorm(); double t = exp( - d * d / denom ); scalars->SetComponent( i, 0, t ); } } else if ( mode == COLORIZATION_CONSTANT ) { for ( unsigned int i = 0; i < pointData->GetNumberOfTuples(); ++i ) { scalars->SetComponent( i, 0, scalar ); } } polyData->Modified(); pointData->Update(); return true; }
bool mitk::SurfaceDeformationInteractor3D::ExecuteAction | ( | Action * | action, |
mitk::StateEvent const * | stateEvent | ||
) | [protected, virtual] |
Method called in HandleEvent after Statechange.
look up which object method is associated to the given action and call the method
Each statechange has actions, which can be assigned by it's number. If you are developing a new statemachine, declare all your operations here and send them to Undo-Controller and to the Data. Object- and group-EventId can also be accessed through static methods from OperationEvent
Reimplemented from mitk::StateMachine.
Definition at line 138 of file mitkSurfaceDeformationInteractor3D.cpp.
References mitk::AcCHECKOBJECT, mitk::AcDESELECTOBJECT, mitk::AcDONOTHING, mitk::AcINITMOVE, mitk::AcMODIFY, mitk::AcMOVE, mitk::AcSELECTPICKEDOBJECT, mitk::EIDNO, mitk::EIDYES, QuadProgPP::exp(), mitk::BaseData::Expand(), mitk::Action::GetActionId(), mitk::WheelEvent::GetDelta(), mitk::DisplayPositionEvent::GetDisplayPosition(), mitk::StateEvent::GetEvent(), mitk::BaseData::GetGeometry(), mitk::RenderingManager::GetInstance(), mitk::DisplayPositionEvent::GetPickedObjectNode(), mitk::BaseRenderer::GetRenderWindow(), mitk::BaseRenderer::GetTime(), mitk::BaseRenderer::GetTimeStep(), mitk::Surface::GetVtkPolyData(), mitk::DisplayPositionEvent::GetWorldPosition(), MITK_ERROR, mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS, mitk::RenderingManager::RequestUpdateAll(), QuadProgPP::t(), and mitk::BaseData::UpdateOutputInformation().
{ bool ok = false; // Get data object mitk::BaseData *data = m_DataNode->GetData(); if ( data == NULL ) { MITK_ERROR << "No data object present!"; return ok; } // Get mitk::Event and extract renderer const mitk::Event *event = stateEvent->GetEvent(); mitk::BaseRenderer *renderer = NULL; vtkRenderWindow *renderWindow = NULL; vtkRenderWindowInteractor *renderWindowInteractor = NULL; if ( event != NULL ) { renderer = event->GetSender(); if ( renderer != NULL ) { renderWindow = renderer->GetRenderWindow(); if ( renderWindow != NULL ) { renderWindowInteractor = renderWindow->GetInteractor(); } } } // Check if we have a DisplayPositionEvent const mitk::DisplayPositionEvent *dpe = dynamic_cast< const mitk::DisplayPositionEvent * >( stateEvent->GetEvent() ); if ( dpe != NULL ) { m_PickedSurfaceNode = dpe->GetPickedObjectNode(); m_CurrentPickedPoint = dpe->GetWorldPosition(); m_CurrentPickedDisplayPoint = dpe->GetDisplayPosition(); } // Get the timestep to also support 3D+t int timeStep = 0; mitk::ScalarType timeInMS = 0.0; if ( renderer != NULL ) { timeStep = renderer->GetTimeStep( data ); timeInMS = renderer->GetTime(); } // Extract surface m_Surface = dynamic_cast< Surface * >( data ); if ( m_Surface != NULL ) { m_PolyData = m_Surface->GetVtkPolyData( timeStep ); } else { m_PolyData = NULL; } // Extract surface normal from surface (if existent, otherwise use default) vtkPointData *pointData = m_PolyData->GetPointData(); if ( pointData != NULL ) { vtkDataArray *normal = m_PolyData->GetPointData()->GetVectors( "planeNormal" ); if ( normal != NULL ) { m_ObjectNormal[0] = normal->GetComponent( 0, 0 ); m_ObjectNormal[1] = normal->GetComponent( 0, 1 ); m_ObjectNormal[2] = normal->GetComponent( 0, 2 ); } } // Get geometry object m_Geometry = data->GetGeometry( timeStep ); // Make sure that the data (if time-resolved) has enough entries; // if not, create the required extra ones (empty) data->Expand( timeStep+1 ); switch (action->GetActionId()) { case AcDONOTHING: ok = true; break; case AcCHECKOBJECT: { // Check if an object is present at the current mouse position m_PickedSurface = NULL; m_PickedPolyData = NULL; if ( m_PickedSurfaceNode != NULL ) { m_PickedSurface = dynamic_cast< mitk::Surface * >( m_PickedSurfaceNode->GetData() ); if ( m_PickedSurface != NULL ) { m_PickedPolyData = m_PickedSurface->GetVtkPolyData( timeStep ); } } mitk::StateEvent *newStateEvent; if ( (m_PickedSurfaceNode == m_DataNode) && (m_PickedSurface != NULL) ) { // Yes: object will be selected newStateEvent = new mitk::StateEvent( EIDYES ); // Disable VTK interactor until MITK interaction has been completed if ( renderWindowInteractor != NULL ) { renderWindowInteractor->Disable(); } } else { // No: back to start state newStateEvent = new mitk::StateEvent( EIDNO ); // Re-enable VTK interactor (may have been disabled previously) if ( renderWindowInteractor != NULL ) { renderWindowInteractor->Enable(); } } this->HandleEvent( newStateEvent ); // Colorized surface at current picked position m_SurfaceColorizationCenter = m_CurrentPickedPoint; ok = true; break; } case AcDESELECTOBJECT: { // Color object white m_DataNode->SetColor( 1.0, 1.0, 1.0 ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Colorize surface / wireframe as inactive this->ColorizeSurface( m_PolyData, m_SurfaceColorizationCenter, COLORIZATION_CONSTANT, -1.0 ); ok = true; break; } case AcSELECTPICKEDOBJECT: { // Color object red m_DataNode->SetColor( 1.0, 0.0, 0.0 ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Colorize surface / wireframe dependend on distance from picked point this->ColorizeSurface( m_PolyData, m_SurfaceColorizationCenter, COLORIZATION_GAUSS ); ok = true; break; } case AcINITMOVE: { // Store current picked point m_InitialPickedPoint = m_CurrentPickedPoint; m_InitialPickedDisplayPoint = m_CurrentPickedDisplayPoint; if ( renderWindowInteractor != NULL ) { vtkInteractorObserver::ComputeDisplayToWorld( renderWindowInteractor->GetInteractorStyle()->GetCurrentRenderer(), m_InitialPickedDisplayPoint[0], m_InitialPickedDisplayPoint[1], 0.0, //m_InitialInteractionPickedPoint[2], m_InitialPickedPointWorld ); } // Make deep copy of vtkPolyData interacted on m_OriginalPolyData->DeepCopy( m_PolyData ); ok = true; break; } case AcMOVE: { if ( renderWindowInteractor != NULL ) { vtkInteractorObserver::ComputeDisplayToWorld( renderWindowInteractor->GetInteractorStyle()->GetCurrentRenderer(), m_CurrentPickedDisplayPoint[0], m_CurrentPickedDisplayPoint[1], 0.0, //m_InitialInteractionPickedPoint[2], m_CurrentPickedPointWorld ); } // Calculate mouse move in 3D space mitk::Vector3D interactionMove; interactionMove[0] = m_CurrentPickedPointWorld[0] - m_InitialPickedPointWorld[0]; interactionMove[1] = m_CurrentPickedPointWorld[1] - m_InitialPickedPointWorld[1]; interactionMove[2] = m_CurrentPickedPointWorld[2] - m_InitialPickedPointWorld[2]; // Transform mouse move into geometry space data->UpdateOutputInformation(); // make sure that the Geometry is up-to-date mitk::Point3D origin; origin.Fill( 0.0 ); m_Geometry->WorldToIndex( origin, interactionMove, interactionMove ); // Get picked point and transform into local coordinates mitk::Point3D pickedPoint; m_Geometry->WorldToIndex( m_InitialPickedPoint, pickedPoint ); mitk::Vector3D v1 = pickedPoint.GetVectorFromOrigin(); mitk::Vector3D v2 = m_ObjectNormal * (interactionMove * m_ObjectNormal); vtkPoints *originalPoints = m_OriginalPolyData->GetPoints(); vtkPoints *deformedPoints = m_PolyData->GetPoints(); double denom = m_GaussSigma * m_GaussSigma * 2; double point[3]; for ( unsigned int i = 0; i < deformedPoints->GetNumberOfPoints(); ++i ) { // Get original point vtkFloatingPointType *originalPoint = originalPoints->GetPoint( i ); mitk::Vector3D v0; v0[0] = originalPoint[0]; v0[1] = originalPoint[1]; v0[2] = originalPoint[2]; // Calculate distance of this point from line through picked point double d = itk::CrossProduct( m_ObjectNormal, (v1 - v0) ).GetNorm(); mitk::Vector3D t = v2 * exp( - d * d / denom ); point[0] = originalPoint[0] + t[0]; point[1] = originalPoint[1] + t[1]; point[2] = originalPoint[2] + t[2]; deformedPoints->SetPoint( i, point ); } // Make sure that surface is colorized at initial picked position // as long as we are in deformation state m_SurfaceColorizationCenter = m_InitialPickedPoint; m_PolyData->Modified(); m_Surface->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll( mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS ); ok = false; break; } case AcMODIFY: { // Check if we have an mitk::WheelEvent const mitk::WheelEvent *we = dynamic_cast< const mitk::WheelEvent * >( stateEvent->GetEvent() ); if ( we == NULL ) { ok = true; break; } m_GaussSigma += (double) (we->GetDelta()) / 20;; if ( m_GaussSigma < 10.0 ) { m_GaussSigma = 10.0; } else if ( m_GaussSigma > 128.0 ) { m_GaussSigma = 128.0; } // Colorize surface / wireframe dependend on sigma and distance from picked point this->ColorizeSurface( m_PolyData, m_SurfaceColorizationCenter, COLORIZATION_GAUSS ); mitk::RenderingManager::GetInstance()->RequestUpdateAll( mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS ); ok = true; break; } default: return Superclass::ExecuteAction( action, stateEvent ); } return ok; }
virtual const char* mitk::SurfaceDeformationInteractor3D::GetClassName | ( | ) | const [virtual] |
Reimplemented from mitk::Interactor.
static Pointer mitk::SurfaceDeformationInteractor3D::New | ( | const char * | _arga, |
DataNode * | _argb, | ||
int | _argc | ||
) | [inline, static] |
Definition at line 47 of file mitkSurfaceDeformationInteractor3D.h.
Referenced by SurfaceDeformationInteractor3D().
:
static Pointer mitk::SurfaceDeformationInteractor3D::New | ( | const char * | _arga, |
DataNode * | _argb | ||
) | [inline, static] |
NewMacro with two parameters for calling itk::Lightobject::New(..) method.
Reimplemented from mitk::Interactor.
Definition at line 48 of file mitkSurfaceDeformationInteractor3D.h.
:
void mitk::SurfaceDeformationInteractor3D::SetPrecision | ( | ScalarType | precision ) |
Sets the amount of precision.