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

mitk::PaintbrushTool Class Reference
[Interaction ClassesClasses related to InteractiveSegmentation]

Paintbrush tool for InteractiveSegmentation. More...

#include <mitkPaintbrushTool.h>

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

List of all members.

Public Types

typedef PaintbrushTool Self
typedef FeedbackContourTool Superclass
typedef itk::SmartPointer< SelfPointer
typedef itk::SmartPointer
< const Self
ConstPointer

Public Member Functions

virtual const char * GetClassName () const
void SetSize (int value)

Public Attributes

Message1< int > SizeChanged

Protected Member Functions

 PaintbrushTool (int paintingPixelValue=1)
virtual ~PaintbrushTool ()
virtual void Activated ()
 Called when the tool gets activated (registered to mitk::GlobalInteraction).
virtual void Deactivated ()
 Called when the tool gets deactivated (unregistered from mitk::GlobalInteraction).
virtual bool OnMousePressed (Action *, const StateEvent *)
virtual bool OnMouseMoved (Action *, const StateEvent *)
virtual bool OnMouseReleased (Action *, const StateEvent *)
virtual bool OnInvertLogic (Action *, const StateEvent *)
void UpdateContour (const StateEvent *stateEvent)

Protected Attributes

int m_PaintingPixelValue
Contour::Pointer m_MasterContour
int m_LastContourSize

Static Protected Attributes

static int m_Size = 1

Detailed Description

Paintbrush tool for InteractiveSegmentation.

See also:
FeedbackContourTool
ExtractImageFilter
OverwriteSliceImageFilter

Simple paintbrush drawing tool. Right now there are only circular pens of varying size.

Warning:
Only to be instantiated by mitk::ToolManager.
Author:
maleike

Definition at line 46 of file mitkPaintbrushTool.h.


Member Typedef Documentation

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

Reimplemented from mitk::FeedbackContourTool.

Reimplemented in mitk::DrawPaintbrushTool, and mitk::ErasePaintbrushTool.

Definition at line 53 of file mitkPaintbrushTool.h.

typedef itk::SmartPointer<Self> mitk::PaintbrushTool::Pointer

Reimplemented from mitk::FeedbackContourTool.

Reimplemented in mitk::DrawPaintbrushTool, and mitk::ErasePaintbrushTool.

Definition at line 53 of file mitkPaintbrushTool.h.

Reimplemented from mitk::FeedbackContourTool.

Reimplemented in mitk::DrawPaintbrushTool, and mitk::ErasePaintbrushTool.

Definition at line 53 of file mitkPaintbrushTool.h.

Reimplemented from mitk::FeedbackContourTool.

Reimplemented in mitk::DrawPaintbrushTool, and mitk::ErasePaintbrushTool.

Definition at line 53 of file mitkPaintbrushTool.h.


Constructor & Destructor Documentation

mitk::PaintbrushTool::PaintbrushTool ( int  paintingPixelValue = 1 ) [protected]

Definition at line 29 of file mitkPaintbrushTool.cpp.

References m_MasterContour, and mitk::StateMachine::New().

:FeedbackContourTool("PressMoveReleaseWithCTRLInversionAllMouseMoves"),
 m_PaintingPixelValue(paintingPixelValue),
 m_LastContourSize(0) // other than initial mitk::PaintbrushTool::m_Size (around l. 28)
{
  m_MasterContour = Contour::New();
  m_MasterContour->Initialize();

}
mitk::PaintbrushTool::~PaintbrushTool (  ) [protected, virtual]

Definition at line 39 of file mitkPaintbrushTool.cpp.

{
}

Member Function Documentation

void mitk::PaintbrushTool::Activated (  ) [protected, virtual]

Called when the tool gets activated (registered to mitk::GlobalInteraction).

Derived tools should call their parents implementation.

Reimplemented from mitk::Tool.

Definition at line 43 of file mitkPaintbrushTool.cpp.

References mitk::FeedbackContourTool::SetFeedbackContourVisible().

void mitk::PaintbrushTool::Deactivated (  ) [protected, virtual]

Called when the tool gets deactivated (unregistered from mitk::GlobalInteraction).

Derived tools should call their parents implementation.

Reimplemented from mitk::Tool.

Definition at line 50 of file mitkPaintbrushTool.cpp.

References mitk::FeedbackContourTool::SetFeedbackContourVisible().

virtual const char* mitk::PaintbrushTool::GetClassName (  ) const [virtual]
bool mitk::PaintbrushTool::OnInvertLogic ( Action action,
const StateEvent stateEvent 
) [protected, virtual]

Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.

Reimplemented from mitk::SegTool2D.

Definition at line 331 of file mitkPaintbrushTool.cpp.

References mitk::SegTool2D::OnInvertLogic(), mitk::FeedbackContourTool::SetFeedbackContourColor(), and mitk::FeedbackContourTool::SetFeedbackContourColorDefault().

{
  if (!FeedbackContourTool::OnInvertLogic(action, stateEvent)) return false;

  // Inversion only for 0 and 1 as painting values
  if (m_PaintingPixelValue == 1)
  {
    m_PaintingPixelValue = 0;
    FeedbackContourTool::SetFeedbackContourColor( 1.0, 0.0, 0.0 );
  }
  else if (m_PaintingPixelValue == 0)
  {
    m_PaintingPixelValue = 1;
    FeedbackContourTool::SetFeedbackContourColorDefault();
  }

  return true;
}
bool mitk::PaintbrushTool::OnMouseMoved ( Action ,
const StateEvent stateEvent 
) [protected, virtual]

Insert the point to the feedback contour,finish to build the contour and at the same time the painting function

Reimplemented from mitk::SegTool2D.

Definition at line 184 of file mitkPaintbrushTool.cpp.

References mitk::FeedbackContourTool::BackProjectContourFrom2DSlice(), mitk::SegTool2D::DetermineAffectedImageSlice(), mitk::FeedbackContourTool::FillContourInSlice(), mitk::SegTool2D::GetAffectedImageSliceAs2DImage(), mitk::StateEvent::GetEvent(), mitk::BaseData::GetGeometry(), mitk::StateEvent::GetId(), mitk::RenderingManager::GetInstance(), MITK_DEBUG, mitk::OverwriteSliceImageFilter::New(), mitk::Contour::New(), mitk::RenderingManager::RequestUpdate(), ROUND, and mitk::Geometry3D::WorldToIndex().

{
  bool leftMouseButtonPressed(
          stateEvent->GetId() == 530
       || stateEvent->GetId() == 1
       || stateEvent->GetId() == 5
                             );

  const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return false;

  if ( m_LastContourSize != m_Size )
  {
    UpdateContour( stateEvent );
    m_LastContourSize = m_Size;
  }

  DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
  if (!workingNode) return false;

  Image* image = dynamic_cast<Image*>(workingNode->GetData());
  const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldGeometry2D() ) );
  if ( !image || !planeGeometry ) return false;

  int affectedDimension( -1 );
  int affectedSlice( -1 );
  if ( !SegTool2D::DetermineAffectedImageSlice( image, planeGeometry, affectedDimension, affectedSlice ) ) return false;
    
  Point3D worldCoordinates = positionEvent->GetWorldPosition();
  Point3D indexCoordinates;
  image->GetGeometry()->WorldToIndex( worldCoordinates, indexCoordinates );
  MITK_DEBUG << "Mouse at W " << worldCoordinates << std::endl;
  MITK_DEBUG << "Mouse at I " << indexCoordinates << std::endl;

  unsigned int firstDimension(0);
  unsigned int secondDimension(1);
  switch( affectedDimension )
  {
    case 2: // transversal
    default:
      firstDimension = 0;
      secondDimension = 1;
      break;
    case 1: // frontal
      firstDimension = 0;
      secondDimension = 2;
      break;
    case 0: // sagittal
      firstDimension = 1;
      secondDimension = 2;
      break;
  }

  // round to nearest voxel center (abort if this hasn't changed)
  if ( m_Size % 2 == 0 ) // even
  {
    indexCoordinates[firstDimension] = ROUND( indexCoordinates[firstDimension] + 0.5 );
    indexCoordinates[secondDimension] = ROUND( indexCoordinates[secondDimension] + 0.5 );
  }
  else // odd
  {
    indexCoordinates[firstDimension] = ROUND( indexCoordinates[firstDimension]  ) ;//+ 0.5;
    indexCoordinates[secondDimension] = ROUND( indexCoordinates[secondDimension] );// + 0.5;
  }

  static Point3D lastPos; // uninitialized: if somebody finds out how this can be initialized in a one-liner, tell me
  static bool lastLeftMouseButtonPressed(false);
  if ( fabs(indexCoordinates[0] - lastPos[0]) > mitk::eps ||
       fabs(indexCoordinates[1] - lastPos[1]) > mitk::eps ||
       fabs(indexCoordinates[2] - lastPos[2]) > mitk::eps ||
       leftMouseButtonPressed != lastLeftMouseButtonPressed
     )
  {
    lastPos = indexCoordinates;
    lastLeftMouseButtonPressed = leftMouseButtonPressed;
  }
  else
  {
    MITK_DEBUG << "." << std::flush;
    return false;
  }
    
  MITK_DEBUG << "Mouse at C " << indexCoordinates;

  Contour::Pointer contour = Contour::New();
  contour->Initialize();
  for (unsigned int index = 0; index < m_MasterContour->GetNumberOfPoints(); ++index)
  {
    Point3D point = m_MasterContour->GetPoints()->ElementAt(index);
    point[0] += indexCoordinates[ firstDimension ];
    point[1] += indexCoordinates[ secondDimension ];

    MITK_DEBUG << "Contour point [" << index << "] :" << point;
    contour->AddVertex( point );
  }
  
  Image::Pointer slice = SegTool2D::GetAffectedImageSliceAs2DImage( positionEvent, image );
  if ( slice.IsNull() ) return false;

  if (leftMouseButtonPressed)
  {
    FeedbackContourTool::FillContourInSlice( contour, slice, m_PaintingPixelValue );

    OverwriteSliceImageFilter::Pointer slicewriter = OverwriteSliceImageFilter::New();
    slicewriter->SetInput( image );
    slicewriter->SetCreateUndoInformation( true );
    slicewriter->SetSliceImage( slice );
    slicewriter->SetSliceDimension( affectedDimension );
    slicewriter->SetSliceIndex( affectedSlice );
    slicewriter->SetTimeStep( positionEvent->GetSender()->GetTimeStep( image ) );
    slicewriter->Update();
  }

  // visualize contour
  Contour::Pointer displayContour = Contour::New();
  displayContour->Initialize();
  for (unsigned int index = 0; index < contour->GetNumberOfPoints(); ++index)
  {
    Point3D point = contour->GetPoints()->ElementAt(index);
    if ( m_Size % 2 != 0 ) // even
    {
      point[0] += 0.5;
      point[1] += 0.5;
    }
    displayContour->AddVertex( point );
  }

  displayContour = FeedbackContourTool::BackProjectContourFrom2DSlice( slice, displayContour );
  SetFeedbackContour( *displayContour );
  assert( positionEvent->GetSender()->GetRenderWindow() );

  RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );

  return true;
}
bool mitk::PaintbrushTool::OnMousePressed ( Action action,
const StateEvent stateEvent 
) [protected, virtual]

Just show the contour, get one point as the central point and add surrounding points to the contour.

Reimplemented from mitk::SegTool2D.

Definition at line 162 of file mitkPaintbrushTool.cpp.

References mitk::StateEvent::GetEvent(), and mitk::SegTool2D::OnMousePressed().

{
  if (FeedbackContourTool::OnMousePressed( action, stateEvent ))
  {
    const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
    if (positionEvent)
    {
      UpdateContour( stateEvent );
    }
  }
  
  return this->OnMouseMoved(action, stateEvent);
  /*

  return true;
  */
}
bool mitk::PaintbrushTool::OnMouseReleased ( Action ,
const StateEvent  
) [protected, virtual]

Reimplemented from mitk::SegTool2D.

Definition at line 321 of file mitkPaintbrushTool.cpp.

{
  //FeedbackContourTool::SetFeedbackContourVisible(false);

  return true;
}
void mitk::PaintbrushTool::SetSize ( int  value )

Definition at line 56 of file mitkPaintbrushTool.cpp.

{
  m_Size = value;
}
void mitk::PaintbrushTool::UpdateContour ( const StateEvent stateEvent ) [protected]

Definition at line 61 of file mitkPaintbrushTool.cpp.

References mitk::CastToItkImage(), mitk::CastToMitkImage(), mitk::SegTool2D::GetAffectedWorkingSlice(), mitk::StateEvent::GetEvent(), ipMITKSegmentationGetContour8N(), ipMITKSegmentationTYPE, MITK_DEBUG, MITK_INFO, mitkIpPicDescriptor, mitk::Contour::New(), and mitk::Image::New().

{
  // examine stateEvent and create a contour that matches the pixel mask that we are going to draw
  const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return;
  
  Image::Pointer m_WorkingSlice = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );
  if (m_WorkingSlice.IsNull()) return;
  // create a copy of this slice (at least match the pixel sizes/spacings),
  // then draw the desired mask on it and create a contour from it

  // Convert to ipMITKSegmentationTYPE (because getting pixels relys on that data type)
  itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
  CastToItkImage( m_WorkingSlice, correctPixelTypeImage );
  assert (correctPixelTypeImage.IsNotNull() );

  itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
  imageDirection.SetIdentity();
  correctPixelTypeImage->SetDirection(imageDirection);

  Image::Pointer temporarySlice = Image::New();
  CastToMitkImage( correctPixelTypeImage, temporarySlice );

  mitkIpPicDescriptor* stupidClone = mitkIpPicClone( temporarySlice->GetSliceData()->GetPicDescriptor() );
  unsigned int pixelWidth  = m_Size + 1;
  unsigned int pixelHeight = m_Size + 1;

  if ( stupidClone->n[0] <= pixelWidth || stupidClone->n[1] <= pixelHeight )
  {
    MITK_INFO << "Brush size is bigger than your working image. Reconsider this...\n"
                "(Or tell your progammer until (s)he fixes this message.)" << std::endl;
    mitkIpPicFree( stupidClone );
    return;
  }
  
  unsigned int lineLength( stupidClone->n[0] );
  unsigned int oneContourOffset(0);
  float circleCenterX = (float)m_Size / 2.0;
  float circleCenterY = (float)m_Size / 2.0;
  for (unsigned int x = 0; x <= pixelWidth; ++x)
  {
    for (unsigned int y = 0; y <= pixelHeight; ++y)
    {
      unsigned int offset = lineLength * y + x;
      ipMITKSegmentationTYPE* current = (ipMITKSegmentationTYPE*)stupidClone->data + offset;

      float pixelCenterX = x + 0.5;
      float pixelCenterY = y + 0.5;

      float xoff = pixelCenterX - circleCenterX;
      float yoff = pixelCenterY - circleCenterY;

      bool inside = xoff * xoff + yoff * yoff < (m_Size * m_Size) / 4.0; // no idea, if this would work for ellipses
      if (inside)
      {
        *current = 1;
        oneContourOffset = offset;
      }
      else
      {
        *current = 0;
      }
    }
  }
      
  int numberOfContourPoints( 0 );
  int newBufferSize( 0 );
  float* contourPoints = ipMITKSegmentationGetContour8N( stupidClone, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
  if (!contourPoints) 
  {
    mitkIpPicFree( stupidClone );
    return;
  }

  // copy point from float* to mitk::Contour 
  Contour::Pointer contourInImageIndexCoordinates = Contour::New();
  contourInImageIndexCoordinates->Initialize();
  Point3D newPoint;
  //ipMITKSegmentationGetContour8N returns all points, which causes vtk warnings, since the first and the last points are coincident.
  //leaving the last point out, the contour is still drawn correctly
  for (int index = 0; index < numberOfContourPoints-1; ++index)
  {
    newPoint[0] = contourPoints[ 2 * index + 0 ] - circleCenterX; // master contour should be centered around (0,0)
    newPoint[1] = contourPoints[ 2 * index + 1] - circleCenterY;
    newPoint[2] = 0.0;
    MITK_DEBUG << "Point [" << index << "] (" << newPoint[0] << ", " << newPoint[1] << ")" << std::endl;

    contourInImageIndexCoordinates->AddVertex( newPoint );
  }

  free(contourPoints);

  m_MasterContour = contourInImageIndexCoordinates;

  mitkIpPicFree( stupidClone );
}

Member Data Documentation

Definition at line 81 of file mitkPaintbrushTool.h.

Definition at line 79 of file mitkPaintbrushTool.h.

Referenced by PaintbrushTool().

Definition at line 76 of file mitkPaintbrushTool.h.

int mitk::PaintbrushTool::m_Size = 1 [static, protected]

Definition at line 77 of file mitkPaintbrushTool.h.

Definition at line 51 of file mitkPaintbrushTool.h.


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