Commit 022d847a authored by David Adair's avatar David Adair Committed by David Gobbi
Browse files

BUG: InteractorStyleImage not getting image for Window/Level.

If an observer has not been set for the StartWindowLevelEvent, then
the vtkInteractorStyleImage is supposed to automatically locate the
last vtkImageActor or vtkImageSlice that was added to the renderer,
and apply the window/level to that actor.  However, there was a bug
where if a non-image actor was added to the renderer after the image
actor, the image actor would not be found.  This patch fixes that bug.

Change-Id: I8c6aaa4e14e712f5ea94c24b38620a00e6bb0d73
parent eb9d3002
......@@ -89,6 +89,10 @@ void vtkInteractorStyleImage::StartWindowLevel()
return;
}
this->StartState(VTKIS_WINDOW_LEVEL);
// Get the last (the topmost) image
this->SetCurrentImageToNthImage(-1);
if (this->HandleObservers &&
this->HasObserver(vtkCommand::StartWindowLevelEvent))
{
......@@ -96,9 +100,6 @@ void vtkInteractorStyleImage::StartWindowLevel()
}
else
{
// Get the last (the topmost) image
this->SetCurrentImageToNthImage(-1);
if (this->CurrentImageProperty)
{
vtkImageProperty *property = this->CurrentImageProperty;
......@@ -642,16 +643,25 @@ void vtkInteractorStyleImage::SetCurrentImageToNthImage(int i)
int j = 0;
for (props->InitTraversal(pit); (prop = props->GetNextProp(pit)); )
{
bool foundImageProp = false;
for (prop->InitPathTraversal(); (path = prop->GetNextPath()); )
{
vtkProp *tryProp = path->GetLastNode()->GetViewProp();
if ( (imageProp = vtkImageSlice::SafeDownCast(tryProp)) != 0 )
{
if (j == i) { break; }
if (j == i)
{
foundImageProp = true;
break;
}
imageProp = 0;
j++;
}
}
if (foundImageProp)
{
break;
}
}
if (i < 0)
{
......
......@@ -157,6 +157,14 @@ public:
void SetImageOrientation(const double leftToRight[3],
const double bottomToTop[3]);
// Description:
// Get the current image property, which is set when StartWindowLevel
// is called immediately before StartWindowLevelEvent is generated.
// This is the image property of the topmost vtkImageSlice in the
// renderer or NULL if no image actors are present.
vtkImageProperty *GetCurrentImageProperty() {
return this->CurrentImageProperty; }
protected:
vtkInteractorStyleImage();
~vtkInteractorStyleImage();
......
......@@ -40,6 +40,7 @@ SET(RenderingTestsWithArguments
TestImageSliceMapperOrient3D.cxx
TestImageSliceMapperInterpolation.cxx
TestImageStack.cxx
TestInteractorStyleImageProperty.cxx
TestInteractorTimers.cxx
TestLabelPlacer.cxx
TestLabelPlacer2D.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestInteractorStyleImagePropertyMultiplePropSliceFirst.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkActor2D.h"
#include "vtkInteractorStyleImage.h"
#include "vtkImageProperty.h"
#include "vtkImageData.h"
#include "vtkImageSliceMapper.h"
#include "vtkImageSlice.h"
#include "vtkPNGReader.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkSmartPointer.h"
#include "vtkTestUtilities.h"
#include "vtkTextMapper.h"
int TestInteractorStyleImagePropertyInternal(int argc, char *argv[], int sliceOrder)
{
vtkSmartPointer<vtkPNGReader> reader =
vtkSmartPointer<vtkPNGReader>::New();
char *fileName = vtkTestUtilities::ExpandDataFileName(
argc, argv, "Data/GreenCircle.png");
reader->SetFileName(fileName);
delete[] fileName;
vtkSmartPointer<vtkImageSliceMapper> mapper =
vtkSmartPointer<vtkImageSliceMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkImageSlice> imageSlice =
vtkSmartPointer<vtkImageSlice>::New();
imageSlice->SetMapper(mapper);
vtkSmartPointer<vtkImageProperty> property =
vtkSmartPointer<vtkImageProperty>::New();
property->SetColorWindow(4000);
property->SetColorLevel(2000);
imageSlice->SetProperty(property);
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->ResetCamera();
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkTextMapper> text =
vtkSmartPointer<vtkTextMapper>::New();
text->SetInput("Text");
vtkSmartPointer<vtkActor2D> textActor =
vtkSmartPointer<vtkActor2D>::New();
textActor->SetMapper(text);
textActor->PickableOff();
switch(sliceOrder)
{
case 0:
//Adding the slice to the renderer before the other prop.
renderer->AddViewProp(imageSlice);
renderer->AddViewProp(textActor);
break;
case 1:
//Only add the slice if there should not be a prop.
renderer->AddViewProp(imageSlice);
break;
case 2:
//Adding the slice to the renderer after the other prop.
renderer->AddViewProp(textActor);
renderer->AddViewProp(imageSlice);
break;
default:
cerr << "Invalid sliceOrder parameter in TestInteractorStyleImagePropertyInternal." << std::endl;
return 1;
}
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
style->SetCurrentRenderer(renderer);
renderWindowInteractor->SetInteractorStyle(style);
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
//The StartWindowLevel event is not activated until the function
//OnLeftButtonDown is called. Call it to force the event to trigger
//the chain of methods to set the ImageProperty.
style->OnLeftButtonDown();
int retVal = ((style->GetCurrentImageProperty()) ? 1:0);
if (retVal)
{
cerr << "TestInteractorStyleImagePropertyInternal failed with sliceOrder parameter " << sliceOrder << "." << std::endl;
}
//retVal is 0 if property not found. Returns 1 on failure, 0 on success.
return !retVal;
}
int TestInteractorStyleImageProperty(int argc, char *argv[])
{
bool res = true;
// Tests with slice before prop.
if (TestInteractorStyleImagePropertyInternal(argc, argv, 0) != 0)
{
res = false;
}
// Tests with no additional prop.
if (TestInteractorStyleImagePropertyInternal(argc, argv, 1) != 0)
{
res = false;
}
// Tests with slice after prop.
if (TestInteractorStyleImagePropertyInternal(argc, argv, 2) != 0)
{
res = false;
}
return (res ? EXIT_SUCCESS : EXIT_FAILURE);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment