由于vtk9不在有vtk7那样的插件,可以直接拖动到QWidget中,但我们可以手动创建,其实效果是相同的。
class vtkResliceCursorCallback : public vtkCommand
{
public:
static vtkResliceCursorCallback *New()
{
return new vtkResliceCursorCallback;
}
void Execute(vtkObject *caller, unsigned long ev,
void *callData) override
{
if (ev == vtkResliceCursorWidget::WindowLevelEvent ||
ev == vtkCommand::WindowLevelEvent ||
ev == vtkResliceCursorWidget::ResliceThicknessChangedEvent)
{
// Render everything
for (int i = 0; i < 3; i++)
{
this->RCW[i]->Render();
}
this->IPW[0]->GetInteractor()->GetRenderWindow()->Render();
return;
}
vtkImagePlaneWidget* ipw =
dynamic_cast<vtkImagePlaneWidget*>(caller);
if (ipw)
{
double* wl = static_cast<double*>(callData);
if (ipw == this->IPW[0])
{
this->IPW[1]->SetWindowLevel(wl[0], wl[1], 1);
this->IPW[2]->SetWindowLevel(wl[0], wl[1], 1);
}
else if (ipw == this->IPW[1])
{
this->IPW[0]->SetWindowLevel(wl[0], wl[1], 1);
this->IPW[2]->SetWindowLevel(wl[0], wl[1], 1);
}
else if (ipw == this->IPW[2])
{
this->IPW[0]->SetWindowLevel(wl[0], wl[1], 1);
this->IPW[1]->SetWindowLevel(wl[0], wl[1], 1);
}
}
vtkResliceCursorWidget *rcw = dynamic_cast<
vtkResliceCursorWidget *>(caller);
if (rcw)
{
vtkResliceCursorLineRepresentation *rep = dynamic_cast<
vtkResliceCursorLineRepresentation *>(rcw->GetRepresentation());
// Although the return value is not used, we keep the get calls
// in case they had side-effects
rep->GetResliceCursorActor()->GetCursorAlgorithm()->GetResliceCursor();
for (int i = 0; i < 3; i++)
{
vtkPlaneSource *ps = static_cast<vtkPlaneSource *>(
this->IPW[i]->GetPolyDataAlgorithm());
ps->SetOrigin(this->RCW[i]->GetResliceCursorRepresentation()->
GetPlaneSource()->GetOrigin());
ps->SetPoint1(this->RCW[i]->GetResliceCursorRepresentation()->
GetPlaneSource()->GetPoint1());
ps->SetPoint2(this->RCW[i]->GetResliceCursorRepresentation()->
GetPlaneSource()->GetPoint2());
// If the reslice plane has modified, update it on the 3D widget
this->IPW[i]->UpdatePlacement();
}
}
// Render everything
for (int i = 0; i < 3; i++)
{
this->RCW[i]->Render();
}
this->IPW[0]->GetInteractor()->GetRenderWindow()->Render();
}
vtkResliceCursorCallback() {}
vtkImagePlaneWidget* IPW[3];
vtkResliceCursorWidget *RCW[3];
};
TestVTK9FourViewer::TestVTK9FourViewer(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
m_gridLayout = new QGridLayout(this);
QRect rt = this->geometry();
m_gridLayout->setGeometry(rt);
for (size_t i = 0; i < 4; i++)
{
m_pViewWindow[i] = new WeVTKOpenGLWIdget(this);
}
for (size_t i = 0; i < 3; i++)
{
m_pSlicerViewer[i] = vtkSmartPointer<vtkResliceImageViewer>::New();
m_renderWindow[i] = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
m_pSlicerViewer[i]->SetRenderWindow(m_renderWindow[i]);
}
m_gridLayout->addWidget(m_pViewWindow[0], 0, 0);
m_gridLayout->addWidget(m_pViewWindow[1], 0, 1);
m_gridLayout->addWidget(m_pViewWindow[2], 1, 0);
m_gridLayout->addWidget(m_pViewWindow[3], 1, 1);
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
reader->SetDirectoryName("D:/imageData/2013-06-04_dcm");
reader->Update();
int imageDims[3];
reader->GetOutput()->GetDimensions(imageDims);
m_pViewWindow[0]->init(reader->GetOutput());
m_pViewWindow[1]->init(reader->GetOutput());
m_pViewWindow[2]->init(reader->GetOutput());
m_pViewWindow[0]->setRenderWindow(m_pSlicerViewer[0]->GetRenderWindow());
m_pSlicerViewer[0]->SetupInteractor(m_pViewWindow[0]->renderWindow()->GetInteractor());
m_pViewWindow[1]->setRenderWindow(m_pSlicerViewer[1]->GetRenderWindow());
m_pSlicerViewer[1]->SetupInteractor(m_pViewWindow[1]->renderWindow()->GetInteractor());
m_pViewWindow[2]->setRenderWindow(m_pSlicerViewer[2]->GetRenderWindow());
m_pSlicerViewer[2]->SetupInteractor(m_pViewWindow[2]->renderWindow()->GetInteractor());
for (int i = 0; i < 3; i++)
{
// make them all share the same reslice cursor object.
vtkResliceCursorLineRepresentation *rep = vtkResliceCursorLineRepresentation::SafeDownCast(m_pSlicerViewer[i]->GetResliceCursorWidget()->GetRepresentation());
m_pSlicerViewer[i]->SetResliceCursor(m_pSlicerViewer[0]->GetResliceCursor());
rep->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(i);
m_pSlicerViewer[i]->SetInputData(reader->GetOutput());
m_pSlicerViewer[i]->SetSliceOrientation(i);
m_pSlicerViewer[i]->SetResliceModeToAxisAligned();
}
vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New();
picker->SetTolerance(0.005);
vtkSmartPointer<vtkProperty> ipwProp = vtkSmartPointer<vtkProperty>::New();
vtkSmartPointer< vtkRenderer > ren = vtkSmartPointer< vtkRenderer >::New();
vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
m_pViewWindow[3]->setRenderWindow(renderWindow);
m_pViewWindow[3]->renderWindow()->AddRenderer(ren);
vtkRenderWindowInteractor *iren = m_pViewWindow[3]->interactor();
for (int i = 0; i < 3; i++)
{
planeWidget[i] = vtkSmartPointer<vtkImagePlaneWidget>::New();
planeWidget[i]->SetInteractor(iren);
planeWidget[i]->SetPicker(picker);
planeWidget[i]->RestrictPlaneToVolumeOn();
double color[3] = { 0, 0, 0 };
color[i] = 1;
planeWidget[i]->GetPlaneProperty()->SetColor(color);
color[0] /= 4.0;
color[1] /= 4.0;
color[2] /= 4.0;
m_pSlicerViewer[i]->GetRenderer()->SetBackground(color);
planeWidget[i]->SetTexturePlaneProperty(ipwProp);
planeWidget[i]->TextureInterpolateOff();
planeWidget[i]->SetResliceInterpolateToLinear();
planeWidget[i]->SetInputConnection(reader->GetOutputPort());
planeWidget[i]->SetPlaneOrientation(i);
planeWidget[i]->SetSliceIndex(imageDims[i] / 2);
planeWidget[i]->DisplayTextOn();
planeWidget[i]->SetDefaultRenderer(ren);
planeWidget[i]->SetWindowLevel(1358, -27);
planeWidget[i]->On();
planeWidget[i]->InteractionOn();
}
vtkSmartPointer<vtkResliceCursorCallback> cbk = vtkSmartPointer<vtkResliceCursorCallback>::New();
for (int i = 0; i < 3; i++)
{
cbk->IPW[i] = planeWidget[i];
cbk->RCW[i] = m_pSlicerViewer[i]->GetResliceCursorWidget();
m_pSlicerViewer[i]->GetResliceCursorWidget()->AddObserver(
vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk);
m_pSlicerViewer[i]->GetResliceCursorWidget()->AddObserver(
vtkResliceCursorWidget::WindowLevelEvent, cbk);
m_pSlicerViewer[i]->GetResliceCursorWidget()->AddObserver(
vtkResliceCursorWidget::ResliceThicknessChangedEvent, cbk);
m_pSlicerViewer[i]->GetResliceCursorWidget()->AddObserver(
vtkResliceCursorWidget::ResetCursorEvent, cbk);
m_pSlicerViewer[i]->GetInteractorStyle()->AddObserver(
vtkCommand::WindowLevelEvent, cbk);
// Make them all share the same color map.
m_pSlicerViewer[i]->SetLookupTable(m_pSlicerViewer[0]->GetLookupTable());
planeWidget[i]->GetColorMap()->SetLookupTable(m_pSlicerViewer[0]->GetLookupTable());
//planeWidget[i]->GetColorMap()->SetInput(riw[i]->GetResliceCursorWidget()->GetResliceCursorRepresentation()->GetColorMap()->GetInput());
planeWidget[i]->SetColorMap(m_pSlicerViewer[i]->GetResliceCursorWidget()->GetResliceCursorRepresentation()->GetColorMap());
}
}