void mitk::SurfaceToImageFilter::Stencil3DImage(int time)
{
  const mitk::TimeGeometry *surfaceTimeGeometry = GetInput()->GetTimeGeometry();
  const mitk::TimeGeometry *imageTimeGeometry = GetImage()->GetTimeGeometry();

  // Convert time step from image time-frame to surface time-frame
  mitk::TimePointType matchingTimePoint = imageTimeGeometry->TimeStepToTimePoint(time);
  mitk::TimeStepType surfaceTimeStep = surfaceTimeGeometry->TimePointToTimeStep(matchingTimePoint);

  vtkPolyData * polydata = ( (mitk::Surface*)GetInput() )->GetVtkPolyData( surfaceTimeStep );

  vtkSmartPointer<vtkTransformPolyDataFilter> move=vtkTransformPolyDataFilter::New();
  move->SetInputData(polydata);
  move->ReleaseDataFlagOn();

  vtkSmartPointer<vtkTransform> transform=vtkTransform::New();
  Geometry3D* geometry = surfaceTimeGeometry->GetGeometryForTimeStep( surfaceTimeStep );
  geometry->TransferItkToVtkTransform();
  transform->PostMultiply();
  transform->Concatenate(geometry->GetVtkTransform()->GetMatrix());
  // take image geometry into account. vtk-Image information will be changed to unit spacing and zero origin below.
  Geometry3D* imageGeometry = imageTimeGeometry->GetGeometryForTimeStep(time);
  imageGeometry->TransferItkToVtkTransform();
  transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse());
  move->SetTransform(transform);

  vtkSmartPointer<vtkPolyDataNormals> normalsFilter = vtkPolyDataNormals::New();
  normalsFilter->SetFeatureAngle(50);
  normalsFilter->SetConsistency(1);
  normalsFilter->SetSplitting(1);
  normalsFilter->SetFlipNormals(0);
  normalsFilter->ReleaseDataFlagOn();

  normalsFilter->SetInputConnection(move->GetOutputPort() );

  vtkSmartPointer<vtkPolyDataToImageStencil> surfaceConverter = vtkPolyDataToImageStencil::New();
  surfaceConverter->SetTolerance( 0.0 );
  surfaceConverter->ReleaseDataFlagOn();

  surfaceConverter->SetInputConnection( normalsFilter->GetOutputPort() );

  mitk::Image::Pointer binaryImage = mitk::Image::New();

  if (m_MakeOutputBinary)
  {
    binaryImage->Initialize(mitk::MakeScalarPixelType<unsigned char>(), *this->GetImage()->GetTimeGeometry());

    unsigned int size = sizeof(unsigned char);
    for (unsigned int i = 0; i < binaryImage->GetDimension(); ++i)
      size *= binaryImage->GetDimension(i);

    mitk::ImageWriteAccessor accessor( binaryImage );
    memset( accessor.GetData(), 1, size );
  }

  vtkImageData *image = m_MakeOutputBinary
    ? binaryImage->GetVtkImageData(time)
    : const_cast<mitk::Image *>(this->GetImage())->GetVtkImageData(time);

  // Create stencil and use numerical minimum of pixel type as background value
  vtkSmartPointer<vtkImageStencil> stencil = vtkImageStencil::New();
  stencil->SetInputData(image);
  stencil->ReverseStencilOff();
  stencil->ReleaseDataFlagOn();
  stencil->SetStencilConnection(surfaceConverter->GetOutputPort());

  stencil->SetBackgroundValue(m_MakeOutputBinary ? 0 : m_BackgroundValue);
  stencil->Update();

  mitk::Image::Pointer output = this->GetOutput();
  output->SetVolume( stencil->GetOutput()->GetScalarPointer(), time );
  MITK_INFO << "stencil ref count: " << stencil->GetReferenceCount() << std::endl;
}
Example #2
0
bool mitk::WiiMoteInteractor::FixedRotationAndTranslation(const mitk::WiiMoteAllDataEvent* wiiMoteEvent)
{

  Geometry3D* geometry = this->TransformCurrentDataInGeometry3D();

  m_OrientationX = wiiMoteEvent->GetOrientationX();
  m_OrientationY = wiiMoteEvent->GetOrientationY();
  m_OrientationZ = wiiMoteEvent->GetOrientationZ();

  ScalarType pitchSpeed = wiiMoteEvent->GetPitchSpeed();
  ScalarType rollSpeed = wiiMoteEvent->GetRollSpeed();
  ScalarType yawSpeed = wiiMoteEvent->GetYawSpeed();

  // angle x
  if(std::abs(pitchSpeed) < 200)
    pitchSpeed = 0;

  m_xAngle += (pitchSpeed / 1500);

  // angle y
  if(std::abs(rollSpeed) < 200)
    rollSpeed = 0;

  m_yAngle += (rollSpeed / 1500);

  // angle z
  if(std::abs(yawSpeed) < 200)
    yawSpeed = 0;

  m_zAngle += (yawSpeed / 1500);

  if(  std::abs(pitchSpeed) > 200
    || std::abs(rollSpeed) > 200
    || std::abs(yawSpeed) > 200)
  {
    m_InRotation = true;
    //// depending on a combination of the
    //// orientation the angleX wil be altered
    //// because the range from roll is limited
    //// range: -90° to 90° by the wiimote
    //if(wiiMoteEvent->GetOrientationZ() < 0)
    //{
    //  // value is positive
    //  if(wiiMoteEvent->GetOrientationX() > 0)
    //  {
    //    // the degree measured decreases after it reaches
    //    // in the "real" world the 90 degree angle
    //    // (rotation to the right side)
    //    // therefore it needs to artificially increased

    //    // measured value drops -> computated angle increases
    //    angleX = 90 - angleX;

    //    // now add the "new" angle to 90 degree threshold
    //    angleX += 90;
    //  }
    //  // value is negative
    //  else if(wiiMoteEvent->GetOrientationX() < 0)
    //  {
    //    // the degree measured increases after it reaches
    //    // in the "real" world -90 degree
    //    // (rotation to the left side)
    //    // therefore it needs to be artificially decreased
    //    // (example -90 -> -70, but -110 is needed)

    //    // measured value increases -> computated angle decreases
    //    angleX = 90 + angleX;

    //    // invert the algebraic sign, because it is the "negative"
    //    // side of the rotation
    //    angleX = -angleX;

    //    // now add the negative value to the -90 degree threshold
    //    // to decrease the value further
    //    angleX -= 90;
    //  }
    //  else if(wiiMoteEvent->GetOrientationX() == 0)
    //  {
    //    // i.e. wiimote is flipped upside down
    //    angleX = 180;
    //  }
    //}

    //rotation
    vtkTransform *vtkTransform = vtkTransform::New();

    //copy m_vtkMatrix to m_VtkIndexToWorldTransform
    geometry->TransferItkToVtkTransform();

    //////m_VtkIndexToWorldTransform as vtkLinearTransform*
    vtkTransform->SetMatrix(geometry->GetVtkTransform()->GetMatrix());

    // rotation from center is different
    // from rotation while translated
    // hence one needs the center of the object
    Point3D center = geometry->GetOrigin();

    vtkTransform->PostMultiply();
    vtkTransform->Translate(-center[0], -center[1], -center[2]);
    //vtkTransform->RotateWXYZ(angle, rotationVector[0], rotationVector[1], rotationVector[2]);

    vtkTransform->RotateX(m_xAngle);

    vtkTransform->RotateY(m_zAngle);

    vtkTransform->RotateZ(m_yAngle);

    vtkTransform->Translate(center[0], center[1], center[2]);
    vtkTransform->PreMultiply();

    geometry->SetIndexToWorldTransformByVtkMatrix(vtkTransform->GetMatrix());
    geometry->Modified();

    // indicate modification of data tree node
    m_DataNode->Modified();

    vtkTransform->Delete();

    //update rendering
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();

    return true;

  }
  else if(!m_InRotation)
  {
    float xValue = wiiMoteEvent->GetXAcceleration();
    float yValue = wiiMoteEvent->GetYAcceleration();
    float zValue = wiiMoteEvent->GetZAcceleration();

    float pitch = wiiMoteEvent->GetPitch();
    float roll = wiiMoteEvent->GetRoll();

    // substracts the proportionate force
    // applied by gravity depending on the
    // orientation

    float sinP = sin(pitch/180.0 * M_PI);
    float cosP = cos(pitch/180.0 * M_PI);
    float sinR = sin(roll/180.0 * M_PI);
    float cosR = cos(roll/180.0 * M_PI);

    // x acceleration
    if(m_OrientationZ >= 0)
      xValue = xValue - sinR * cosP;
    else
      xValue = xValue + sinR * cosP;

    // against drift
    if(std::abs(xValue) < 0.2)
      xValue = 0;

    // y acceleration
    yValue = yValue + sinP;

    // against drift
    if(std::abs(yValue) < 0.2)
      yValue = 0;

    // z acceleration
    zValue = zValue - cosP * cosR;

    // against drift
    if(std::abs(zValue) < 0.3)
      zValue = 0;

    // simple integration over time
    // resulting in velocity
    switch(m_TranslationMode)
    {
    case 1:
      m_xVelocity -= xValue;
      m_yVelocity -= yValue;
      m_zVelocity += zValue;


      // 1 = movement to the right
      // initially starts with negative acceleration
      // 2 = movement to the left
      // initially starts with positive acceleration
      if(  m_xVelocity > 0 && xValue > 0  // 1
        || m_xVelocity < 0 && xValue < 0) // 2
      {
        m_xVelocity += xValue;
      }
      else if( m_xVelocity > 0 && xValue < 0  // 1
        || m_xVelocity < 0 && xValue > 0)     // 2
      {
        m_xVelocity -= xValue;
      }
      break;

    case 3:

      m_yVelocity -= yValue;
      break;
    case 4:

      // 1 = movement up
      // initially starts with positive acceleration
      // 2 = movement down
      // initially starts with negative acceleration
      if(  m_zVelocity > 0 && zValue < 0  // 1
        || m_zVelocity < 0 && zValue > 0) // 2
      {
        m_zVelocity -= zValue;
      }
      else if(m_zVelocity > 0 && zValue > 0 // 1
        || m_zVelocity < 0 && zValue < 0)   // 2
      {
        m_zVelocity += zValue;
      }
      break;
    }

    // sets the mode of the translation
    // depending on the initial velocity
    if(  std::abs(m_xVelocity) > std::abs(m_yVelocity)
      && std::abs(m_xVelocity) > std::abs(m_zVelocity) )
    {
      m_TranslationMode = 2;
      m_yVelocity = 0;
      m_zVelocity = 0;
    }
    else if( std::abs(m_yVelocity) > std::abs(m_xVelocity)
      && std::abs(m_yVelocity) > std::abs(m_zVelocity) )
    {
      m_TranslationMode = 3;
      m_xVelocity = 0;
      m_zVelocity = 0;
    }
    else if(std::abs(m_zVelocity) > std::abs(m_xVelocity)
      && std::abs(m_zVelocity) > std::abs(m_yVelocity) )
    {
      m_TranslationMode = 4;
      m_xVelocity = 0;
      m_yVelocity = 0;
    }

    // translation
    mitk::Vector3D movementVector;
    movementVector.SetElement(0,m_xVelocity);
    movementVector.SetElement(1,m_yVelocity);
    movementVector.SetElement(2,m_zVelocity);

    geometry->Translate(movementVector);

    // indicate modification of data tree node
    m_DataNode->Modified();

    // update rendering
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();

    return true;
  }

  return false;
}
void mitk::SurfaceToImageFilter::Stencil3DImage(int time)
{
  const mitk::TimeSlicedGeometry *surfaceTimeGeometry = GetInput()->GetTimeSlicedGeometry();
  const mitk::TimeSlicedGeometry *imageTimeGeometry = GetImage()->GetTimeSlicedGeometry();

  // Convert time step from image time-frame to surface time-frame
  int surfaceTimeStep = surfaceTimeGeometry->TimeStepToTimeStep( imageTimeGeometry, time );
  
  vtkPolyData * polydata = ( (mitk::Surface*)GetInput() )->GetVtkPolyData( surfaceTimeStep );

  vtkTransformPolyDataFilter * move=vtkTransformPolyDataFilter::New();
  move->SetInput(polydata);
  move->ReleaseDataFlagOn();

  vtkTransform *transform=vtkTransform::New();
  Geometry3D* geometry = surfaceTimeGeometry->GetGeometry3D( surfaceTimeStep );
  geometry->TransferItkToVtkTransform();
  transform->PostMultiply();
  transform->Concatenate(geometry->GetVtkTransform()->GetMatrix());
  // take image geometry into account. vtk-Image information will be changed to unit spacing and zero origin below.
  Geometry3D* imageGeometry = imageTimeGeometry->GetGeometry3D(time);
  imageGeometry->TransferItkToVtkTransform();
  transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse());
  move->SetTransform(transform);
  transform->Delete();

  vtkPolyDataNormals * normalsFilter = vtkPolyDataNormals::New();
  normalsFilter->SetFeatureAngle(50);
  normalsFilter->SetConsistency(1);
  normalsFilter->SetSplitting(1);
  normalsFilter->SetFlipNormals(0);
  normalsFilter->ReleaseDataFlagOn();

  normalsFilter->SetInput( move->GetOutput() );
  move->Delete();

  vtkPolyDataToImageStencil * surfaceConverter = vtkPolyDataToImageStencil::New();
  surfaceConverter->SetTolerance( 0.0 );
  surfaceConverter->ReleaseDataFlagOn();

  surfaceConverter->SetInput( normalsFilter->GetOutput() );
  normalsFilter->Delete();

  vtkImageData *image = const_cast< mitk::Image * >(this->GetImage())->GetVtkImageData( time );
  
  // Create stencil and use numerical minimum of pixel type as background value
  vtkImageStencil * stencil = vtkImageStencil::New();
  stencil->SetInput( image );
  stencil->ReverseStencilOff();
  stencil->ReleaseDataFlagOn();
  stencil->SetStencil( surfaceConverter->GetOutput() );
  surfaceConverter->Delete();

  if (m_MakeOutputBinary)
  {
    stencil->SetBackgroundValue( image->GetScalarTypeMin() );

    vtkImageThreshold * threshold = vtkImageThreshold::New();
    threshold->SetInput( stencil->GetOutput() );
    threshold->ThresholdByLower( image->GetScalarTypeMin() );
    threshold->ReplaceInOn();
    threshold->ReplaceOutOn();
    threshold->SetInValue( 0 );
    threshold->SetOutValue( 1 );
    threshold->SetOutputScalarTypeToUnsignedChar();
    threshold->Update();

    mitk::Image::Pointer output = this->GetOutput();
    output->SetVolume( threshold->GetOutput()->GetScalarPointer(), time );

    threshold->Delete();
  }
  else
  {
    stencil->SetBackgroundValue( m_BackgroundValue );
    stencil->Update();

    mitk::Image::Pointer output = this->GetOutput();
    output->SetVolume( stencil->GetOutput()->GetScalarPointer(), time );
    MITK_INFO << "stencil ref count: " << stencil->GetReferenceCount() << std::endl;
  }
  stencil->Delete();
}