Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkSetRegionTool.h"
00019
00020 #include "mitkToolManager.h"
00021 #include "mitkOverwriteSliceImageFilter.h"
00022
00023 #include "ipSegmentation.h"
00024
00025 #include "mitkBaseRenderer.h"
00026
00027 mitk::SetRegionTool::SetRegionTool(int paintingPixelValue)
00028 :FeedbackContourTool("PressMoveReleaseWithCTRLInversion"),
00029 m_PaintingPixelValue(paintingPixelValue),
00030 m_FillContour(false),
00031 m_StatusFillWholeSlice(false)
00032 {
00033 }
00034
00035 mitk::SetRegionTool::~SetRegionTool()
00036 {
00037 }
00038
00039 void mitk::SetRegionTool::Activated()
00040 {
00041 Superclass::Activated();
00042 }
00043
00044 void mitk::SetRegionTool::Deactivated()
00045 {
00046 Superclass::Deactivated();
00047 }
00048
00049 bool mitk::SetRegionTool::OnMousePressed (Action* action, const StateEvent* stateEvent)
00050 {
00051 if (!FeedbackContourTool::OnMousePressed( action, stateEvent )) return false;
00052
00053 const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
00054 if (!positionEvent) return false;
00055
00056
00057 Image::Pointer workingSlice = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );
00058 if ( workingSlice.IsNull() ) return false;
00059
00060
00061 const Geometry3D* sliceGeometry = workingSlice->GetGeometry();
00062 itk::Index<2> projectedPointIn2D;
00063 sliceGeometry->WorldToIndex( positionEvent->GetWorldPosition(), projectedPointIn2D );
00064 if ( !sliceGeometry->IsIndexInside( projectedPointIn2D ) )
00065 {
00066 MITK_ERROR << "point apparently not inside segmentation slice" << std::endl;
00067 return false;
00068 }
00069
00070
00071 itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
00072 CastToItkImage( workingSlice, correctPixelTypeImage );
00073 assert (correctPixelTypeImage.IsNotNull() );
00074
00075
00076
00077
00078
00079
00080 itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
00081 imageDirection.SetIdentity();
00082 correctPixelTypeImage->SetDirection(imageDirection);
00083
00084 Image::Pointer temporarySlice = Image::New();
00085
00086 CastToMitkImage( correctPixelTypeImage, temporarySlice );
00087
00088
00089
00090 mitkIpPicDescriptor* originalPicSlice = temporarySlice->GetSliceData()->GetPicDescriptor();
00091
00092 int m_SeedPointMemoryOffset = projectedPointIn2D[1] * originalPicSlice->n[0] + projectedPointIn2D[0];
00093
00094 if ( m_SeedPointMemoryOffset >= static_cast<int>( originalPicSlice->n[0] * originalPicSlice->n[1] ) ||
00095 m_SeedPointMemoryOffset < 0 )
00096 {
00097 MITK_ERROR << "Memory offset calculation if mitk::SetRegionTool has some serious flaw! Aborting.." << std::endl;
00098 return false;
00099 }
00100
00101
00102
00103
00104 unsigned int oneContourOffset = static_cast<unsigned int>( m_SeedPointMemoryOffset );
00105
00120 unsigned int size = originalPicSlice->n[0] * originalPicSlice->n[1];
00121
00122
00123
00124 ipMITKSegmentationTYPE* data = static_cast<ipMITKSegmentationTYPE*>(originalPicSlice->data);
00125
00126 if ( data[oneContourOffset] == 0 )
00127 {
00128 for ( ; oneContourOffset < size; ++oneContourOffset )
00129 {
00130 if ( data[oneContourOffset] > 0 ) break;
00131 }
00132 }
00133 else if ( data[oneContourOffset] == 1 )
00134 {
00135 unsigned int lastValidPixel = size-1;
00136 bool inSeg = true;
00137 for ( ; oneContourOffset < size; ++oneContourOffset )
00138 {
00139 if ( ( data[oneContourOffset] == 0 ) && inSeg )
00140 {
00141 inSeg = false;
00142 lastValidPixel = oneContourOffset - 1;
00143 break;
00144 }
00145 else
00146 {
00147 inSeg = true;
00148 }
00149
00150 }
00151 oneContourOffset = lastValidPixel;
00152 }
00153 else
00154 {
00155 MITK_ERROR << "Fill/Erase was never intended to work with other than binary images." << std::endl;
00156 m_FillContour = false;
00157 return false;
00158 }
00159
00160 if (oneContourOffset == size)
00161 {
00162 m_FillContour = false;
00163 return false;
00164 }
00165
00166 int numberOfContourPoints( 0 );
00167 int newBufferSize( 0 );
00168
00169 float* contourPoints = ipMITKSegmentationGetContour8N( originalPicSlice, oneContourOffset, numberOfContourPoints, newBufferSize );
00170
00171
00172 assert(contourPoints == NULL || numberOfContourPoints > 0);
00173
00174 bool cursorInsideContour = ipMITKSegmentationIsInsideContour( contourPoints, numberOfContourPoints, projectedPointIn2D[0], projectedPointIn2D[1]);
00175
00176
00177 m_FillContour = cursorInsideContour;
00178
00179 if (m_FillContour)
00180 {
00181
00182 Contour::Pointer contourInImageIndexCoordinates = Contour::New();
00183 contourInImageIndexCoordinates->Initialize();
00184 Point3D newPoint;
00185 for (int index = 0; index < numberOfContourPoints; ++index)
00186 {
00187 newPoint[0] = contourPoints[ 2 * index + 0 ];
00188 newPoint[1] = contourPoints[ 2 * index + 1];
00189 newPoint[2] = 0;
00190
00191 contourInImageIndexCoordinates->AddVertex( newPoint );
00192 }
00193
00194 m_SegmentationContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice, contourInImageIndexCoordinates, true );
00195
00196
00197 FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );
00198
00199 FeedbackContourTool::SetFeedbackContourVisible(true);
00200 mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
00201 }
00202
00203
00204 {
00205
00206 Contour::Pointer contourInImageIndexCoordinates = Contour::New();
00207 contourInImageIndexCoordinates->Initialize();
00208 Point3D newPoint;
00209 newPoint[0] = 0; newPoint[1] = 0; newPoint[2] = 0.0;
00210 contourInImageIndexCoordinates->AddVertex( newPoint );
00211 newPoint[0] = originalPicSlice->n[0]; newPoint[1] = 0; newPoint[2] = 0.0;
00212 contourInImageIndexCoordinates->AddVertex( newPoint );
00213 newPoint[0] = originalPicSlice->n[0]; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0;
00214 contourInImageIndexCoordinates->AddVertex( newPoint );
00215 newPoint[0] = 0; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0;
00216 contourInImageIndexCoordinates->AddVertex( newPoint );
00217
00218 m_WholeImageContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice, contourInImageIndexCoordinates, true );
00219
00220
00221 FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );
00222
00223 FeedbackContourTool::SetFeedbackContourVisible(true);
00224 mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
00225 }
00226
00227
00228 free(contourPoints);
00229
00230 return true;
00231 }
00232
00233 bool mitk::SetRegionTool::OnMouseReleased(Action* action, const StateEvent* stateEvent)
00234 {
00235
00236 FeedbackContourTool::SetFeedbackContourVisible(false);
00237
00238 const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
00239 if (!positionEvent) return false;
00240
00241 assert( positionEvent->GetSender()->GetRenderWindow() );
00242 mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
00243
00244 if (!m_FillContour && !m_StatusFillWholeSlice) return true;
00245
00246 if (!FeedbackContourTool::OnMouseReleased( action, stateEvent )) return false;
00247
00248 DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
00249 if (!workingNode) return false;
00250
00251 Image* image = dynamic_cast<Image*>(workingNode->GetData());
00252 const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldGeometry2D() ) );
00253 if ( !image || !planeGeometry ) return false;
00254
00255 int affectedDimension( -1 );
00256 int affectedSlice( -1 );
00257 if ( FeedbackContourTool::DetermineAffectedImageSlice( image, planeGeometry, affectedDimension, affectedSlice ) )
00258 {
00259
00260 Image::Pointer slice = FeedbackContourTool::GetAffectedImageSliceAs2DImage( positionEvent, image );
00261
00262 if ( slice.IsNull() )
00263 {
00264 MITK_ERROR << "Unable to extract slice." << std::endl;
00265 return false;
00266 }
00267
00268 Contour* feedbackContour( FeedbackContourTool::GetFeedbackContour() );
00269 Contour::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, false, false );
00270
00271 if (projectedContour.IsNull()) return false;
00272
00273 FeedbackContourTool::FillContourInSlice( projectedContour, slice, m_PaintingPixelValue );
00274
00275
00276 OverwriteSliceImageFilter::Pointer slicewriter = OverwriteSliceImageFilter::New();
00277 slicewriter->SetInput( image );
00278 slicewriter->SetCreateUndoInformation( true );
00279 slicewriter->SetSliceImage( slice );
00280 slicewriter->SetSliceDimension( affectedDimension );
00281 slicewriter->SetSliceIndex( affectedSlice );
00282 slicewriter->SetTimeStep( positionEvent->GetSender()->GetTimeStep( image ) );
00283 slicewriter->Update();
00284
00285
00286 assert( positionEvent->GetSender()->GetRenderWindow() );
00287 mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
00288 }
00289 else
00290 {
00291 MITK_ERROR << "FeedbackContourTool could not determine which slice of the image you are drawing on." << std::endl;
00292 }
00293
00294 m_WholeImageContourInWorldCoordinates = NULL;
00295 m_SegmentationContourInWorldCoordinates = NULL;
00296
00297 return true;
00298 }
00299
00303 bool mitk::SetRegionTool::OnInvertLogic(Action* action, const StateEvent* stateEvent)
00304 {
00305 if (!FeedbackContourTool::OnInvertLogic(action, stateEvent)) return false;
00306
00307 const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
00308 if (!positionEvent) return false;
00309
00310 if (m_StatusFillWholeSlice)
00311 {
00312
00313 if (m_SegmentationContourInWorldCoordinates.IsNotNull())
00314 FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );
00315 mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
00316 }
00317 else
00318 {
00319
00320 if (m_WholeImageContourInWorldCoordinates.IsNotNull())
00321 FeedbackContourTool::SetFeedbackContour( *m_WholeImageContourInWorldCoordinates );
00322 mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
00323 }
00324
00325 m_StatusFillWholeSlice = !m_StatusFillWholeSlice;
00326
00327 return true;
00328 }
00329