void mitk::OverwriteSliceImageFilter::GenerateData()
{
  //
  // this is the place to implement the major part of undo functionality (bug #491)
  // here we have to create undo/do operations
  //
  // WHO is the operation actor? This object may not be destroyed ever (design of undo stack)!
  // -> some singleton method of this filter?
  //
  // neccessary additional objects:
  //  - something that executes the operations
  //  - the operation class (must hold a binary diff or something)
  //  - observer commands to know when the image is deleted (no further action then, perhaps even remove the operations from the undo stack)
  //
  Image::ConstPointer input = ImageToImageFilter::GetInput(0);
  Image::ConstPointer input3D = input;

  Image::ConstPointer slice = m_SliceImage;

  if ( input.IsNull() || slice.IsNull() ) return;

  switch (m_SliceDimension)
  {
    default:
    case 2:
      m_Dimension0 = 0;
      m_Dimension1 = 1;
      break;
    case 1:
      m_Dimension0 = 0;
      m_Dimension1 = 2;
      break;
    case 0:
      m_Dimension0 = 1;
      m_Dimension1 = 2;
      break;
  }

  if ( slice->GetDimension() < 2 || input->GetDimension() > 4 ||
       slice->GetDimension(0) != input->GetDimension(m_Dimension0) ||
       slice->GetDimension(1) != input->GetDimension(m_Dimension1) ||
       m_SliceIndex >= input->GetDimension(m_SliceDimension)
     )
  {
   itkExceptionMacro("Slice and image dimensions differ or slice index is too large. Sorry, cannot work like this.");
   return;
  }

  if ( input->GetDimension() == 4 )
  {
    ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
    timeSelector->SetInput( input );
    timeSelector->SetTimeNr( m_TimeStep );
    timeSelector->UpdateLargestPossibleRegion();
    input3D = timeSelector->GetOutput();
  }

  if ( m_SliceDifferenceImage.IsNull() ||
       m_SliceDifferenceImage->GetDimension(0) != m_SliceImage->GetDimension(0) ||
       m_SliceDifferenceImage->GetDimension(1) != m_SliceImage->GetDimension(1) )
  {
    m_SliceDifferenceImage = mitk::Image::New();
    mitk::PixelType pixelType( mitk::MakeScalarPixelType<short signed int>() );
    m_SliceDifferenceImage->Initialize( pixelType, 2, m_SliceImage->GetDimensions() );
  }

  //MITK_INFO << "Overwriting slice " << m_SliceIndex << " in dimension " << m_SliceDimension << " at time step " << m_TimeStep << std::endl;
  // this will do a long long if/else to find out both pixel types
  AccessFixedDimensionByItk( input3D, ItkImageSwitch, 3 );

  SegmentationInterpolationController* interpolator = SegmentationInterpolationController::InterpolatorForImage( input );
  if (interpolator)
  {
    interpolator->BlockModified(true);
    interpolator->SetChangedSlice( m_SliceDifferenceImage, m_SliceDimension, m_SliceIndex, m_TimeStep );
  }

  if ( m_CreateUndoInformation )
  {
    // create do/undo operations (we don't execute the doOp here, because it has already been executed during calculation of the diff image
    ApplyDiffImageOperation* doOp = new ApplyDiffImageOperation( OpTEST, const_cast<Image*>(input.GetPointer()), m_SliceDifferenceImage, m_TimeStep, m_SliceDimension, m_SliceIndex );
    ApplyDiffImageOperation* undoOp = new ApplyDiffImageOperation( OpTEST, const_cast<Image*>(input.GetPointer()), m_SliceDifferenceImage, m_TimeStep, m_SliceDimension, m_SliceIndex );
    undoOp->SetFactor( -1.0 );
    OperationEvent* undoStackItem = new OperationEvent( DiffImageApplier::GetInstanceForUndo(), doOp, undoOp, this->EventDescription(m_SliceDimension, m_SliceIndex, m_TimeStep) );
    UndoController::GetCurrentUndoModel()->SetOperationEvent( undoStackItem );
  }

  // this image is modified (good to know for the renderer)
  input->Modified();

  if (interpolator)
  {
    interpolator->BlockModified(false);
  }
}
Example #2
0
void mitk::DiffImageApplier::ExecuteOperation( Operation* operation )
{
  ApplyDiffImageOperation* imageOperation = dynamic_cast<ApplyDiffImageOperation*>( operation );
  if (    imageOperation                        // we actually have the kind of operation that we can handle
       && imageOperation->IsImageStillValid() ) // AND the image is not yet deleted
  {
    m_Image = imageOperation->GetImage();
    Image::Pointer image3D = m_Image; // will be changed later in case of 3D+t

    m_SliceDifferenceImage = imageOperation->GetDiffImage();
    m_TimeStep = imageOperation->GetTimeStep();

    m_Factor = imageOperation->GetFactor();

    if ( m_SliceDifferenceImage->GetDimension() == 2 )
    {
      m_SliceIndex = imageOperation->GetSliceIndex();
      m_SliceDimension = imageOperation->GetSliceDimension();
      switch (m_SliceDimension)
      {
        default:
        case 2:
          m_Dimension0 = 0;
          m_Dimension1 = 1;
          break;
        case 1:
          m_Dimension0 = 0;
          m_Dimension1 = 2;
          break;
        case 0:
          m_Dimension0 = 1;
          m_Dimension1 = 2;
          break;
      }

      if ( m_SliceDifferenceImage->GetDimension() != 2 || (m_Image->GetDimension() < 3 || m_Image->GetDimension() > 4) ||
           m_SliceDifferenceImage->GetDimension(0) != m_Image->GetDimension(m_Dimension0) ||
           m_SliceDifferenceImage->GetDimension(1) != m_Image->GetDimension(m_Dimension1) ||
           m_SliceIndex >= m_Image->GetDimension(m_SliceDimension)
         )
      {
       itkExceptionMacro("Slice and image dimensions differ or slice index is too large. Sorry, cannot work like this.");
       return;
      }

      if ( m_Image->GetDimension() == 4 )
      {
        ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
        timeSelector->SetInput( m_Image );
        timeSelector->SetTimeNr( m_TimeStep );
        timeSelector->UpdateLargestPossibleRegion();
        image3D = timeSelector->GetOutput();
      }

       // this will do a long long if/else to find out both pixel types
      AccessFixedDimensionByItk( image3D, ItkImageSwitch2DDiff, 3 );

      if ( m_Factor == 1 || m_Factor == -1 )
      {
        if ( m_Factor == -1 )
        {
          // multiply diff pixels by factor and then send this diff slice
          AccessFixedDimensionByItk( m_SliceDifferenceImage, ItkInvertPixelValues, 2 );
        }

        // just send the diff to SegmentationInterpolationController
        SegmentationInterpolationController* interpolator = SegmentationInterpolationController::InterpolatorForImage( m_Image );
        if (interpolator)
        {
          interpolator->BlockModified(true);
          interpolator->SetChangedSlice( m_SliceDifferenceImage, m_SliceDimension, m_SliceIndex, m_TimeStep );
        }
        
        m_Image->Modified();

        if (interpolator)
        {
          interpolator->BlockModified(false);
        }

        if ( m_Factor == -1 ) // return to normal values
        {
          AccessFixedDimensionByItk( m_SliceDifferenceImage, ItkInvertPixelValues, 2 );
        }
      }
      else // no trivial case, too lazy to do something else
      {
        m_Image->Modified(); // check if interpolation is called. prefer to send diff directly
      }

      RenderingManager::GetInstance()->RequestUpdateAll();
    }
    else if ( m_SliceDifferenceImage->GetDimension() == 3 )
    { 
      // ...
      if (  m_SliceDifferenceImage->GetDimension(0) != m_Image->GetDimension(0) ||
            m_SliceDifferenceImage->GetDimension(1) != m_Image->GetDimension(1) ||
            m_SliceDifferenceImage->GetDimension(2) != m_Image->GetDimension(2) ||
            m_TimeStep >= m_Image->GetDimension(3)
         )
        {
         itkExceptionMacro("Diff image size differs from original image size. Sorry, cannot work like this.");
         return;
        }

      if ( m_Image->GetDimension() == 4 )
      {
        ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
        timeSelector->SetInput( m_Image );
        timeSelector->SetTimeNr( m_TimeStep );
        timeSelector->UpdateLargestPossibleRegion();
        image3D = timeSelector->GetOutput();
      }

      // this will do a long long if/else to find out both pixel types
      AccessFixedDimensionByItk( image3D, ItkImageSwitch3DDiff, 3 );

      if ( m_Factor == 1 || m_Factor == -1 )
      {
        if ( m_Factor == -1 )
        {
          // multiply diff pixels by factor and then send this diff slice
          AccessFixedDimensionByItk( m_SliceDifferenceImage, ItkInvertPixelValues, 3 );
        }

        // just send the diff to SegmentationInterpolationController
        SegmentationInterpolationController* interpolator = SegmentationInterpolationController::InterpolatorForImage( m_Image );
        if (interpolator)
        {
          interpolator->BlockModified(true);
          interpolator->SetChangedVolume( m_SliceDifferenceImage, m_TimeStep );
        }

        m_Image->Modified();

        if (interpolator)
        {
          interpolator->BlockModified(false);
        }

        if ( m_Factor == -1 ) // return to normal values
        {
          AccessFixedDimensionByItk( m_SliceDifferenceImage, ItkInvertPixelValues, 3 );
        }
      }
      else // no trivial case, too lazy to do something else
      {
        m_Image->Modified(); // check if interpolation is called. prefer to send diff directly
      }
      
      RenderingManager::GetInstance()->RequestUpdateAll();
    }
    else
    {
     itkExceptionMacro("Diff image must be 2D or 3D. Sorry, cannot work like this.");
     return;
    }
  }

  m_Image = NULL;
  m_SliceDifferenceImage = NULL;
}