Public Types | Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions

mitk::SurfaceDeformationInteractor3D Class Reference
[Interaction Classes]

Affine interaction with objects in 3D windows. More...

#include <mitkSurfaceDeformationInteractor3D.h>

Inheritance diagram for mitk::SurfaceDeformationInteractor3D:
Inheritance graph
[legend]
Collaboration diagram for mitk::SurfaceDeformationInteractor3D:
Collaboration graph
[legend]

List of all members.

Public Types

typedef
SurfaceDeformationInteractor3D 
Self
typedef Interactor Superclass
typedef itk::SmartPointer< SelfPointer
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)

Detailed Description

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.


Member Typedef Documentation

typedef itk::SmartPointer<const Self> mitk::SurfaceDeformationInteractor3D::ConstPointer

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.

Reimplemented from mitk::Interactor.

Definition at line 46 of file mitkSurfaceDeformationInteractor3D.h.


Member Enumeration Documentation

anonymous enum [protected]
Enumerator:
COLORIZATION_GAUSS 
COLORIZATION_CONSTANT 

Definition at line 79 of file mitkSurfaceDeformationInteractor3D.h.


Constructor & Destructor Documentation

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();
}

Member Function Documentation

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.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines