#include <vtkSmartPointer.h>
#include <vtkObjectFactory.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkActor.h>
// headers needed for this example
#include <vtkImageViewer2.h>
#include <vtkDICOMImageReader.h>
#include <vtkInteractorStyleImage.h>
#include <vtkActor2D.h>
#include <vtkTextProperty.h>
#include <vtkTextMapper.h>
#include <vtkContourFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkPolyDataMapper.h>
#include <vtkOutlineFilter.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
#include <vtkPlaneWidget.h>
#include <vtkImageData.h>
#include <vtkAutoInit.h>
#include <vtkImageReslice.h>
#include <vtkImageMapToColors.h>
#include <vtkMatrix4x4.h>
#include <vtkAxesActor.h>
#include <vtkPlaneSource.h>
#include <vtkCaptionActor2D.h>
#include <vtkNamedColors.h>
#include <vtkLookupTable.h>
#include <vtkImageActor.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
int extent[6];
double spacing[3];
double origin[3];
vtkNew<vtkActor> m_planeActor1;
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;
}
void SetImageMapToColors(vtkImageMapToColors *mapToColors)
{
this->mapToColors = mapToColors;
}
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;
cout << currPos[0] << " " << currPos[1] << endl;;
}
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);
cout << point[2] << " " << center[0] << " " << center[1] << " " << center[2] << endl;
matrix->SetElement(0, 3, center[0]);
matrix->SetElement(1, 3, center[1]);
matrix->SetElement(2, 3, center[2]);
mapToColors->Update();
interactor->Render();
}
else
{
vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(
interactor->GetInteractorStyle());
if (style)
{
style->OnMouseMove();
}
}
}
else if (event == vtkCommand::MouseWheelForwardEvent)
{
}
else if (event == vtkCommand::MouseWheelBackwardEvent)
{
}
}
private:
int Slicing;
vtkImageReslice *ImageReslice;
vtkRenderWindowInteractor *Interactor;
vtkImageMapToColors *mapToColors;
};
//畫座標軸
void createAxes(vtkSmartPointer<vtkRenderer> renderer)
{
//軸
vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
axes->SetTotalLength(400.0, 400.0, 400.0);
axes->SetShaftType(vtkAxesActor::CYLINDER_SHAFT);//設置軸類型圓柱形狀
axes->SetCylinderRadius(0.01);
axes->GetXAxisCaptionActor2D()->SetWidth(0.01);
axes->GetYAxisCaptionActor2D()->SetWidth(0.01);
axes->GetZAxisCaptionActor2D()->SetWidth(0.01);
renderer->AddActor(axes);
}
int main(int argc, char* argv[])
{
//// Verify input arguments
//if (argc != 2)
//{
// std::cout << "Usage: " << argv[0]
// << " FolderName" << std::endl;
// return EXIT_FAILURE;
//}
vtkRenderer *aRenderer = vtkRenderer::New();
vtkRenderer *rRenderer = vtkRenderer::New();
vtkRenderWindow *renWin1 = vtkRenderWindow::New();
vtkRenderWindow *renWin2 = vtkRenderWindow::New();
renWin1->AddRenderer(aRenderer);
renWin2->AddRenderer(rRenderer);
vtkRenderWindowInteractor *iren1 = vtkRenderWindowInteractor::New();
vtkRenderWindowInteractor *iren2 = vtkRenderWindowInteractor::New();
iren1->SetRenderWindow(renWin1);
iren2->SetRenderWindow(renWin2);
createAxes(aRenderer);
//createAxes(rRenderer);
vtkDICOMImageReader *reader = vtkDICOMImageReader::New();
reader->SetDataByteOrderToLittleEndian();
reader->SetDirectoryName("d:/se1");
reader->Update();
//v16->SetDataSpacing(3.2, 3.2, 1.5);
reader->GetOutput()->GetExtent(extent);
reader->GetOutput()->GetSpacing(spacing);
reader->GetOutput()->GetOrigin(origin);
cout << extent[0] << " " << extent[1] << " " << extent[2] << " "
<< extent[3] << " " << extent[4] << " " << extent[5] << " " << endl;
cout << spacing[0] << " " << spacing[1] << " " << spacing[2] << " " << endl;
cout << origin[0] << " " << origin[1] << " " << origin[2] << " " << endl;
//***********************畫垂直於X軸的平面***********************
vtkSmartPointer<vtkPlaneSource> planeSource = vtkSmartPointer<vtkPlaneSource>::New();
planeSource->SetCenter(0, 0, 0);
planeSource->SetPoint1(0, 0, 200);
planeSource->SetPoint2(0, 200, 0);
planeSource->Update();
vtkPolyData *plane = planeSource->GetOutput();
vtkSmartPointer<vtkPolyDataMapper> planeMap = vtkSmartPointer<vtkPolyDataMapper>::New();
planeMap->SetInputData(plane);
//vtkSmartPointer<vtkActor> planeActor = vtkSmartPointer<vtkActor>::New();
m_planeActor1->SetMapper(planeMap);
vtkSmartPointer<vtkNamedColors> planeColor = vtkSmartPointer<vtkNamedColors>::New();
m_planeActor1->GetProperty()->SetColor(planeColor->GetColor3d("Red").GetData());
aRenderer->AddActor(m_planeActor1);
vtkContourFilter *skinExtractor = vtkContourFilter::New();
skinExtractor->SetInputConnection(reader->GetOutputPort());
//skinExtractor->SetValue(0, 500);
vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New();
skinNormals->SetInputConnection(skinExtractor->GetOutputPort());
//skinNormals->SetFeatureAngle(60.0);
vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New();
skinMapper->SetInputConnection(skinNormals->GetOutputPort());
skinMapper->ScalarVisibilityOff();
vtkActor *skin = vtkActor::New();
skin->SetMapper(skinMapper);
vtkOutlineFilter *outlineData = vtkOutlineFilter::New();
outlineData->SetInputConnection(reader->GetOutputPort());
vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New();
mapOutline->SetInputConnection(outlineData->GetOutputPort());
vtkActor *outline = vtkActor::New();
outline->SetMapper(mapOutline);
outline->GetProperty()->SetColor(0, 0, 0);
vtkCamera *aCamera = vtkCamera::New();
aCamera->SetViewUp(0, 0, -1);
aCamera->SetPosition(0, 1, 0);
aCamera->SetFocalPoint(0, 0, 0);
aCamera->ComputeViewPlaneNormal();
aRenderer->AddActor(outline);
aRenderer->AddActor(skin);
aRenderer->SetActiveCamera(aCamera);
aRenderer->ResetCamera();
aCamera->Dolly(1.5);
aRenderer->ResetCameraClippingRange();
aRenderer->SetBackground(1.0, 1.0, 1.0);
renWin1->SetSize(640, 480);
// Initialize the event loop and then start it.
iren1->Initialize();
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]);
static double axialElements[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
vtkSmartPointer<vtkMatrix4x4> resliceAxes =
vtkSmartPointer<vtkMatrix4x4>::New();
resliceAxes->DeepCopy(axialElements);
resliceAxes->SetElement(0, 3, center[0]);
resliceAxes->SetElement(1, 3, center[1]);
resliceAxes->SetElement(2, 3, center[2]);
vtkSmartPointer<vtkImageReslice> reslice =
vtkSmartPointer<vtkImageReslice>::New();
reslice->SetInputConnection(reader->GetOutputPort());
reslice->SetOutputDimensionality(2);
reslice->SetResliceAxes(resliceAxes);
reslice->SetInterpolationModeToLinear();
vtkSmartPointer<vtkLookupTable> colorTable =
vtkSmartPointer<vtkLookupTable>::New();
colorTable->SetRange(0, 1000);
colorTable->SetValueRange(0.0, 1.0);
colorTable->SetSaturationRange(0.0, 0.0);
colorTable->SetRampToLinear();
colorTable->Build();
vtkSmartPointer<vtkImageMapToColors> colorMap =
vtkSmartPointer<vtkImageMapToColors>::New();
colorMap->SetLookupTable(colorTable);
colorMap->SetInputConnection(reslice->GetOutputPort());
colorMap->Update();
vtkSmartPointer<vtkImageActor> imgActor =
vtkSmartPointer<vtkImageActor>::New();
imgActor->SetInputData(colorMap->GetOutput());
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
rRenderer->AddActor(imgActor);
rRenderer->SetBackground(1.0, 1.0, 1.0);
renWin2->SetSize(640, 480);
iren2->Initialize();
vtkSmartPointer<vtkInteractorStyleImage> imagestyle =
vtkSmartPointer<vtkInteractorStyleImage>::New();
iren2->SetInteractorStyle(imagestyle);
iren2->SetRenderWindow(renWin2);
iren2->Initialize();
vtkSmartPointer<vtkImageInteractionCallback> callback =
vtkSmartPointer<vtkImageInteractionCallback>::New();
callback->SetImageReslice(reslice);
callback->SetInteractor(iren2);
callback->SetImageMapToColors(colorMap);
imagestyle->AddObserver(vtkCommand::MouseMoveEvent, callback);
imagestyle->AddObserver(vtkCommand::LeftButtonPressEvent, callback);
imagestyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);
iren1->Start();
iren2->Start();
reader->Delete();
skinExtractor->Delete();
skinNormals->Delete();
skinMapper->Delete();
skin->Delete();
outlineData->Delete();
mapOutline->Delete();
outline->Delete();
aCamera->Delete();
iren1->Delete();
renWin1->Delete();
aRenderer->Delete();
return 0;
}
//垂直於X軸的截面
static double sagittalElements[16] = {
0, 0,-1, 0,
1, 0, 0, 0,
0,-1, 0, 0,
0, 0, 0, 1 };
//垂直於Y軸的截面
static double coronalElements[16] = {
1, 0, 0, 0,
0, 0, 1, 0,
0,-1, 0, 0,
0, 0, 0, 1 };
//垂直於Z軸的截面
static double sagittalElements[16] = {
1, 0,0, 0,
0, 1, 0, 0,
0,0, 1, 0,
0, 0, 0, 1 };
如果還需要旋轉.
例如:在垂直於X軸的截面的基礎上,繞Z軸旋轉30度(符號滿足右手定則),需要左乘一個繞Z軸的旋轉矩陣