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