mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
264 lines
8.1 KiB
C++
264 lines
8.1 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: ImageSlicing.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.
|
|
|
|
=========================================================================*/
|
|
//
|
|
// This example shows how to load a 3D image into VTK and then reformat
|
|
// that image into a different orientation for viewing. It uses
|
|
// vtkImageReslice for reformatting the image, and uses vtkImageActor
|
|
// and vtkInteractorStyleImage to display the image. This InteractorStyle
|
|
// forces the camera to stay perpendicular to the XY plane.
|
|
//
|
|
// Thanks to David Gobbi of Atamai Inc. for contributing this example.
|
|
//
|
|
|
|
#include "vtkSmartPointer.h"
|
|
#include "vtkImageReader2.h"
|
|
#include "vtkMatrix4x4.h"
|
|
#include "vtkImageReslice.h"
|
|
#include "vtkLookupTable.h"
|
|
#include "vtkImageMapToColors.h"
|
|
#include "vtkImageActor.h"
|
|
#include "vtkRenderer.h"
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkRenderWindowInteractor.h"
|
|
#include "vtkInteractorStyleImage.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkImageMapper3D.h"
|
|
#include "vtkStreamingDemandDrivenPipeline.h"
|
|
#include "vtkInformation.h"
|
|
|
|
// The mouse motion callback, to turn "Slicing" on and off
|
|
class vtkImageInteractionCallback : public vtkCommand
|
|
{
|
|
public:
|
|
|
|
static vtkImageInteractionCallback *New() {
|
|
return new vtkImageInteractionCallback; };
|
|
|
|
vtkImageInteractionCallback() {
|
|
this->Slicing = 0;
|
|
this->ImageReslice = 0;
|
|
this->Interactor = 0; };
|
|
|
|
void SetImageReslice(vtkImageReslice *reslice) {
|
|
this->ImageReslice = reslice; };
|
|
|
|
vtkImageReslice *GetImageReslice() {
|
|
return this->ImageReslice; };
|
|
|
|
void SetInteractor(vtkRenderWindowInteractor *interactor) {
|
|
this->Interactor = interactor; };
|
|
|
|
vtkRenderWindowInteractor *GetInteractor() {
|
|
return this->Interactor; };
|
|
|
|
virtual void Execute(vtkObject *, unsigned long event, void *)
|
|
{
|
|
vtkRenderWindowInteractor *interactor = this->GetInteractor();
|
|
|
|
int lastPos[2];
|
|
interactor->GetLastEventPosition(lastPos);
|
|
int currPos[2];
|
|
interactor->GetEventPosition(currPos);
|
|
|
|
if (event == vtkCommand::LeftButtonPressEvent)
|
|
{
|
|
this->Slicing = 1;
|
|
}
|
|
else if (event == vtkCommand::LeftButtonReleaseEvent)
|
|
{
|
|
this->Slicing = 0;
|
|
}
|
|
else if (event == vtkCommand::MouseMoveEvent)
|
|
{
|
|
if (this->Slicing)
|
|
{
|
|
vtkImageReslice *reslice = this->ImageReslice;
|
|
|
|
// Increment slice position by deltaY of mouse
|
|
int deltaY = lastPos[1] - currPos[1];
|
|
|
|
reslice->Update();
|
|
double sliceSpacing = reslice->GetOutput()->GetSpacing()[2];
|
|
vtkMatrix4x4 *matrix = reslice->GetResliceAxes();
|
|
// move the center point that we are slicing through
|
|
double point[4];
|
|
double center[4];
|
|
point[0] = 0.0;
|
|
point[1] = 0.0;
|
|
point[2] = sliceSpacing * deltaY;
|
|
point[3] = 1.0;
|
|
matrix->MultiplyPoint(point, center);
|
|
matrix->SetElement(0, 3, center[0]);
|
|
matrix->SetElement(1, 3, center[1]);
|
|
matrix->SetElement(2, 3, center[2]);
|
|
interactor->Render();
|
|
}
|
|
else
|
|
{
|
|
vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(
|
|
interactor->GetInteractorStyle());
|
|
if (style)
|
|
{
|
|
style->OnMouseMove();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
private:
|
|
|
|
// Actions (slicing only, for now)
|
|
int Slicing;
|
|
|
|
// Pointer to vtkImageReslice
|
|
vtkImageReslice *ImageReslice;
|
|
|
|
// Pointer to the interactor
|
|
vtkRenderWindowInteractor *Interactor;
|
|
};
|
|
|
|
// The program entry point
|
|
int main (int argc, char *argv[])
|
|
{
|
|
if (argc < 2)
|
|
{
|
|
cout << "Usage: " << argv[0] << " DATADIR/headsq/quarter" << endl;
|
|
return 1;
|
|
}
|
|
|
|
// Start by loading some data.
|
|
vtkSmartPointer<vtkImageReader2> reader =
|
|
vtkSmartPointer<vtkImageReader2>::New();
|
|
reader->SetFilePrefix(argv[1]);
|
|
reader->SetDataExtent(0, 63, 0, 63, 1, 93);
|
|
reader->SetDataSpacing(3.2, 3.2, 1.5);
|
|
reader->SetDataOrigin(0.0, 0.0, 0.0);
|
|
reader->SetDataScalarTypeToUnsignedShort();
|
|
reader->SetDataByteOrderToLittleEndian();
|
|
reader->UpdateWholeExtent();
|
|
|
|
// Calculate the center of the volume
|
|
reader->Update();
|
|
int extent[6];
|
|
double spacing[3];
|
|
double origin[3];
|
|
|
|
|
|
reader->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent);
|
|
reader->GetOutput()->GetSpacing(spacing);
|
|
reader->GetOutput()->GetOrigin(origin);
|
|
|
|
double center[3];
|
|
center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);
|
|
center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);
|
|
center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);
|
|
|
|
// Matrices for axial, coronal, sagittal, oblique view orientations
|
|
//static double axialElements[16] = {
|
|
// 1, 0, 0, 0,
|
|
// 0, 1, 0, 0,
|
|
// 0, 0, 1, 0,
|
|
// 0, 0, 0, 1 };
|
|
|
|
//static double coronalElements[16] = {
|
|
// 1, 0, 0, 0,
|
|
// 0, 0, 1, 0,
|
|
// 0,-1, 0, 0,
|
|
// 0, 0, 0, 1 };
|
|
|
|
static double sagittalElements[16] = {
|
|
0, 0,-1, 0,
|
|
1, 0, 0, 0,
|
|
0,-1, 0, 0,
|
|
0, 0, 0, 1 };
|
|
|
|
//static double obliqueElements[16] = {
|
|
// 1, 0, 0, 0,
|
|
// 0, 0.866025, -0.5, 0,
|
|
// 0, 0.5, 0.866025, 0,
|
|
// 0, 0, 0, 1 };
|
|
|
|
// Set the slice orientation
|
|
vtkSmartPointer<vtkMatrix4x4> resliceAxes =
|
|
vtkSmartPointer<vtkMatrix4x4>::New();
|
|
resliceAxes->DeepCopy(sagittalElements);
|
|
// Set the point through which to slice
|
|
resliceAxes->SetElement(0, 3, center[0]);
|
|
resliceAxes->SetElement(1, 3, center[1]);
|
|
resliceAxes->SetElement(2, 3, center[2]);
|
|
|
|
// Extract a slice in the desired orientation
|
|
vtkSmartPointer<vtkImageReslice> reslice =
|
|
vtkSmartPointer<vtkImageReslice>::New();
|
|
reslice->SetInputConnection(reader->GetOutputPort());
|
|
reslice->SetOutputDimensionality(2);
|
|
reslice->SetResliceAxes(resliceAxes);
|
|
reslice->SetInterpolationModeToLinear();
|
|
|
|
// Create a greyscale lookup table
|
|
vtkSmartPointer<vtkLookupTable> table =
|
|
vtkSmartPointer<vtkLookupTable>::New();
|
|
table->SetRange(0, 2000); // image intensity range
|
|
table->SetValueRange(0.0, 1.0); // from black to white
|
|
table->SetSaturationRange(0.0, 0.0); // no color saturation
|
|
table->SetRampToLinear();
|
|
table->Build();
|
|
|
|
// Map the image through the lookup table
|
|
vtkSmartPointer<vtkImageMapToColors> color =
|
|
vtkSmartPointer<vtkImageMapToColors>::New();
|
|
color->SetLookupTable(table);
|
|
color->SetInputConnection(reslice->GetOutputPort());
|
|
|
|
// Display the image
|
|
vtkSmartPointer<vtkImageActor> actor =
|
|
vtkSmartPointer<vtkImageActor>::New();
|
|
actor->GetMapper()->SetInputConnection(color->GetOutputPort());
|
|
|
|
vtkSmartPointer<vtkRenderer> renderer =
|
|
vtkSmartPointer<vtkRenderer>::New();
|
|
renderer->AddActor(actor);
|
|
|
|
vtkSmartPointer<vtkRenderWindow> window =
|
|
vtkSmartPointer<vtkRenderWindow>::New();
|
|
window->AddRenderer(renderer);
|
|
|
|
// Set up the interaction
|
|
vtkSmartPointer<vtkInteractorStyleImage> imageStyle =
|
|
vtkSmartPointer<vtkInteractorStyleImage>::New();
|
|
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
|
|
vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
|
interactor->SetInteractorStyle(imageStyle);
|
|
window->SetInteractor(interactor);
|
|
window->Render();
|
|
|
|
vtkSmartPointer<vtkImageInteractionCallback> callback =
|
|
vtkSmartPointer<vtkImageInteractionCallback>::New();
|
|
callback->SetImageReslice(reslice);
|
|
callback->SetInteractor(interactor);
|
|
|
|
imageStyle->AddObserver(vtkCommand::MouseMoveEvent, callback);
|
|
imageStyle->AddObserver(vtkCommand::LeftButtonPressEvent, callback);
|
|
imageStyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);
|
|
|
|
// Start interaction
|
|
// The Start() method doesn't return until the window is closed by the user
|
|
interactor->Start();
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|