You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
300 lines
8.3 KiB
300 lines
8.3 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkImageViewer.cxx,v $
|
|
|
|
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 "vtkImageViewer.h"
|
|
|
|
#include "vtkActor2D.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkInteractorStyleImage.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkRenderWindowInteractor.h"
|
|
#include "vtkRenderer.h"
|
|
|
|
vtkCxxRevisionMacro(vtkImageViewer, "$Revision: 1.51 $");
|
|
vtkStandardNewMacro(vtkImageViewer);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageViewer::vtkImageViewer()
|
|
{
|
|
this->RenderWindow = vtkRenderWindow::New();
|
|
this->Renderer = vtkRenderer::New();
|
|
this->ImageMapper = vtkImageMapper::New();
|
|
this->Actor2D = vtkActor2D::New();
|
|
|
|
// setup the pipeline
|
|
this->Actor2D->SetMapper(this->ImageMapper);
|
|
this->Renderer->AddActor2D(this->Actor2D);
|
|
this->RenderWindow->AddRenderer(this->Renderer);
|
|
|
|
this->FirstRender = 1;
|
|
|
|
this->Interactor = 0;
|
|
this->InteractorStyle = 0;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageViewer::~vtkImageViewer()
|
|
{
|
|
this->ImageMapper->Delete();
|
|
this->Actor2D->Delete();
|
|
this->RenderWindow->Delete();
|
|
this->Renderer->Delete();
|
|
|
|
if (this->Interactor)
|
|
{
|
|
this->Interactor->Delete();
|
|
}
|
|
if (this->InteractorStyle)
|
|
{
|
|
this->InteractorStyle->Delete();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageViewer::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
os << indent << "ImageMapper:\n";
|
|
this->ImageMapper->PrintSelf(os, indent.GetNextIndent());
|
|
os << indent << "RenderWindow:\n";
|
|
this->RenderWindow->PrintSelf(os, indent.GetNextIndent());
|
|
os << indent << "Renderer:\n";
|
|
this->Renderer->PrintSelf(os, indent.GetNextIndent());
|
|
os << indent << "Actor2D:\n";
|
|
this->Actor2D->PrintSelf(os, indent.GetNextIndent());
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageViewer::SetSize(int a[2])
|
|
{
|
|
this->SetSize(a[0],a[1]);
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageViewer::SetPosition(int a[2])
|
|
{
|
|
this->SetPosition(a[0],a[1]);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
class vtkImageViewerCallback : public vtkCommand
|
|
{
|
|
public:
|
|
static vtkImageViewerCallback *New() { return new vtkImageViewerCallback; }
|
|
|
|
void Execute(vtkObject *caller,
|
|
unsigned long event,
|
|
void *vtkNotUsed(callData))
|
|
{
|
|
if (this->IV->GetInput() == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Reset
|
|
|
|
if (event == vtkCommand::ResetWindowLevelEvent)
|
|
{
|
|
this->IV->GetInput()->UpdateInformation();
|
|
this->IV->GetInput()->SetUpdateExtent
|
|
(this->IV->GetInput()->GetWholeExtent());
|
|
this->IV->GetInput()->Update();
|
|
double *range = this->IV->GetInput()->GetScalarRange();
|
|
this->IV->SetColorWindow(range[1] - range[0]);
|
|
this->IV->SetColorLevel(0.5 * (range[1] + range[0]));
|
|
this->IV->Render();
|
|
return;
|
|
}
|
|
|
|
// Start
|
|
|
|
if (event == vtkCommand::StartWindowLevelEvent)
|
|
{
|
|
this->InitialWindow = this->IV->GetColorWindow();
|
|
this->InitialLevel = this->IV->GetColorLevel();
|
|
return;
|
|
}
|
|
|
|
// Adjust the window level here
|
|
|
|
vtkInteractorStyleImage *isi =
|
|
static_cast<vtkInteractorStyleImage *>(caller);
|
|
|
|
int *size = this->IV->GetRenderWindow()->GetSize();
|
|
double window = this->InitialWindow;
|
|
double level = this->InitialLevel;
|
|
|
|
// Compute normalized delta
|
|
|
|
double dx = 4.0 * (isi->GetWindowLevelCurrentPosition()[0] -
|
|
isi->GetWindowLevelStartPosition()[0]) / size[0];
|
|
double dy = 4.0 * (isi->GetWindowLevelStartPosition()[1] -
|
|
isi->GetWindowLevelCurrentPosition()[1]) / size[1];
|
|
|
|
// Scale by current values
|
|
|
|
if (fabs(window) > 0.01)
|
|
{
|
|
dx = dx * window;
|
|
}
|
|
else
|
|
{
|
|
dx = dx * (window < 0 ? -0.01 : 0.01);
|
|
}
|
|
if (fabs(level) > 0.01)
|
|
{
|
|
dy = dy * level;
|
|
}
|
|
else
|
|
{
|
|
dy = dy * (level < 0 ? -0.01 : 0.01);
|
|
}
|
|
|
|
// Abs so that direction does not flip
|
|
|
|
if (window < 0.0)
|
|
{
|
|
dx = -1*dx;
|
|
}
|
|
if (level < 0.0)
|
|
{
|
|
dy = -1*dy;
|
|
}
|
|
|
|
// Compute new window level
|
|
|
|
double newWindow = dx + window;
|
|
double newLevel;
|
|
newLevel = level - dy;
|
|
|
|
// Stay away from zero and really
|
|
|
|
if (fabs(newWindow) < 0.01)
|
|
{
|
|
newWindow = 0.01*(newWindow < 0 ? -1 : 1);
|
|
}
|
|
if (fabs(newLevel) < 0.01)
|
|
{
|
|
newLevel = 0.01*(newLevel < 0 ? -1 : 1);
|
|
}
|
|
|
|
this->IV->SetColorWindow(newWindow);
|
|
this->IV->SetColorLevel(newLevel);
|
|
this->IV->Render();
|
|
}
|
|
|
|
vtkImageViewer *IV;
|
|
double InitialWindow;
|
|
double InitialLevel;
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageViewer::SetupInteractor(vtkRenderWindowInteractor *rwi)
|
|
{
|
|
if (this->Interactor && rwi != this->Interactor)
|
|
{
|
|
this->Interactor->Delete();
|
|
}
|
|
if (!this->InteractorStyle)
|
|
{
|
|
this->InteractorStyle = vtkInteractorStyleImage::New();
|
|
vtkImageViewerCallback *cbk = vtkImageViewerCallback::New();
|
|
cbk->IV = this;
|
|
this->InteractorStyle->AddObserver(vtkCommand::WindowLevelEvent, cbk);
|
|
this->InteractorStyle->AddObserver(vtkCommand::StartWindowLevelEvent, cbk);
|
|
this->InteractorStyle->AddObserver(vtkCommand::ResetWindowLevelEvent, cbk);
|
|
cbk->Delete();
|
|
}
|
|
|
|
if (!this->Interactor)
|
|
{
|
|
this->Interactor = rwi;
|
|
rwi->Register(this);
|
|
}
|
|
this->Interactor->SetInteractorStyle(this->InteractorStyle);
|
|
this->Interactor->SetRenderWindow(this->RenderWindow);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageViewer::Render()
|
|
{
|
|
if (this->FirstRender)
|
|
{
|
|
// initialize the size if not set yet
|
|
if (this->RenderWindow->GetSize()[0] == 0 && this->ImageMapper->GetInput())
|
|
{
|
|
// get the size from the mappers input
|
|
this->ImageMapper->GetInput()->UpdateInformation();
|
|
int *ext = this->ImageMapper->GetInput()->GetWholeExtent();
|
|
// if it would be smaller than 150 by 100 then limit to 150 by 100
|
|
int xs = ext[1] - ext[0] + 1;
|
|
int ys = ext[3] - ext[2] + 1;
|
|
this->RenderWindow->SetSize(xs < 150 ? 150 : xs,
|
|
ys < 100 ? 100 : ys);
|
|
}
|
|
this->FirstRender = 0;
|
|
}
|
|
this->RenderWindow->Render();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageViewer::SetOffScreenRendering(int i)
|
|
{
|
|
this->RenderWindow->SetOffScreenRendering(i);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkImageViewer::GetOffScreenRendering()
|
|
{
|
|
return this->RenderWindow->GetOffScreenRendering();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageViewer::OffScreenRenderingOn()
|
|
{
|
|
this->SetOffScreenRendering(1);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageViewer::OffScreenRenderingOff()
|
|
{
|
|
this->SetOffScreenRendering(0);
|
|
}
|
|
|
|
#ifndef VTK_LEGACY_REMOVE
|
|
int vtkImageViewer::GetGrayScaleHint()
|
|
{
|
|
vtkWarningMacro("GetGrayScaleHint deprecated, not required anymore");
|
|
return 0;
|
|
}
|
|
|
|
void vtkImageViewer::SetGrayScaleHint(int vtkNotUsed(a))
|
|
{
|
|
vtkWarningMacro("SetGrayScaleHint deprecated, not required anymore");
|
|
}
|
|
|
|
void vtkImageViewer::GrayScaleHintOn()
|
|
{
|
|
vtkWarningMacro("GrayScaleHintOn deprecated, not required anymore");
|
|
}
|
|
|
|
void vtkImageViewer::GrayScaleHintOff()
|
|
{
|
|
vtkWarningMacro("GrayScaleHintOff deprecated, not required anymore");
|
|
}
|
|
#endif
|
|
|
|
|