VTK + Qt 中未显示 3D 体积
3D volume not showing in VTK + Qt
我尝试使用 VTK 和 Qt 使用 QVTKOpenGLWidget 显示 3D 体积 (https://midas3.kitware.com/midas/item/34776)。我可以显示坐标轴、球体、圆锥体并与之交互……但 3D 体积不会出现在场景中。
使用 VTK (https://www.vtk.org/Wiki/VTK/Examples/Cxx/VolumeRendering/SmartVolumeMapper) 中的示例时,我可以正确显示音量。
这是最小示例(VTK 8.1.1、Qt 5.10.1、Win10):
CentralWidget::CentralWidget(QWidget *parent=0) : QWidget(parent)
{
mQVTKWidget = new QVTKOpenGLWidget(this);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(mQVTKWidget);
mQVTKWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
mQVTKWidget->SetRenderWindow(renderWindow);
mRenderer = vtkSmartPointer<vtkRenderer>::New();
mQVTKWidget->GetRenderWindow()->AddRenderer(mRenderer);
mRenderer->GradientBackgroundOn();
mRenderer->SetBackground(.8, .8, 1);
mRenderer->SetBackground2(.3, .3, 1);
// Sphere
vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetPhiResolution(30);
sphereSource->SetThetaResolution(30);
sphereSource->SetRadius(50.0);
vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
sphereActor->SetMapper(sphereMapper);
// 3D image: .vti file.
vtkSmartPointer<vtkXMLImageDataReader> reader = vtkSmartPointer<vtkXMLImageDataReader>::New();
reader->SetFileName("NLM Visible Human Project.vti");
reader->Update();
vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::New();
imageData->ShallowCopy(reader->GetOutput());
vtkSmartPointer<vtkSmartVolumeMapper> volumeMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
volumeMapper->SetBlendModeToComposite(); // composite first
volumeMapper->SetInputData(imageData);
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->ShadeOff();
volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity->AddPoint(0.0, 0.0);
compositeOpacity->AddPoint(700.0, 0.0);
compositeOpacity->AddPoint(3600.0, 1.0);
volumeProperty->SetScalarOpacity(compositeOpacity); // composite first.
vtkSmartPointer<vtkColorTransferFunction> color = vtkSmartPointer<vtkColorTransferFunction>::New();
color->AddRGBPoint(0.0, 1.0, 0.0, 0.0);
color->AddRGBPoint(3600.0, 1.0, 0.0, 1.0);
volumeProperty->SetColor(color);
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
// Renderer
mRenderer->AddActor(sphereActor);
mRenderer->AddVolume(volume);
mRenderer->ResetCamera();
// axes
vtkAxesActor *axes = vtkAxesActor::New();
vtkOrientationMarkerWidget *widget = vtkOrientationMarkerWidget::New();
widget->SetDefaultRenderer(mRenderer);
widget->SetOrientationMarker(axes);
widget->SetInteractor(mQVTKWidget->GetRenderWindow()->GetInteractor());
widget->EnabledOn();
vtkSmartPointer<vtkCubeAxesActor> cubeAxesActor =
vtkSmartPointer<vtkCubeAxesActor>::New();
cubeAxesActor->SetBounds(volume->GetBounds());
cubeAxesActor->SetCamera(mRenderer->GetActiveCamera());
mRenderer->AddActor(cubeAxesActor);
}
[编辑]
这是输出的屏幕截图:
我做错了什么?
与 here 中的代码示例进行比较后,我找到了解决方案。错误不在问题的代码片段中,而是在 main() where:
QSurfaceFormat::setDefaultFormat(QVTKOpenGLWidget::defaultFormat());
应替换为:
auto defaultFormat = QVTKOpenGLWidget::defaultFormat();
defaultFormat.setSamples(0);
QSurfaceFormat::setDefaultFormat(defaultFormat);
VTK bug tracker issue #17095 中也讨论了这个问题。
我尝试使用 VTK 和 Qt 使用 QVTKOpenGLWidget 显示 3D 体积 (https://midas3.kitware.com/midas/item/34776)。我可以显示坐标轴、球体、圆锥体并与之交互……但 3D 体积不会出现在场景中。
使用 VTK (https://www.vtk.org/Wiki/VTK/Examples/Cxx/VolumeRendering/SmartVolumeMapper) 中的示例时,我可以正确显示音量。
这是最小示例(VTK 8.1.1、Qt 5.10.1、Win10):
CentralWidget::CentralWidget(QWidget *parent=0) : QWidget(parent)
{
mQVTKWidget = new QVTKOpenGLWidget(this);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(mQVTKWidget);
mQVTKWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
mQVTKWidget->SetRenderWindow(renderWindow);
mRenderer = vtkSmartPointer<vtkRenderer>::New();
mQVTKWidget->GetRenderWindow()->AddRenderer(mRenderer);
mRenderer->GradientBackgroundOn();
mRenderer->SetBackground(.8, .8, 1);
mRenderer->SetBackground2(.3, .3, 1);
// Sphere
vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetPhiResolution(30);
sphereSource->SetThetaResolution(30);
sphereSource->SetRadius(50.0);
vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
sphereActor->SetMapper(sphereMapper);
// 3D image: .vti file.
vtkSmartPointer<vtkXMLImageDataReader> reader = vtkSmartPointer<vtkXMLImageDataReader>::New();
reader->SetFileName("NLM Visible Human Project.vti");
reader->Update();
vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::New();
imageData->ShallowCopy(reader->GetOutput());
vtkSmartPointer<vtkSmartVolumeMapper> volumeMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
volumeMapper->SetBlendModeToComposite(); // composite first
volumeMapper->SetInputData(imageData);
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->ShadeOff();
volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity->AddPoint(0.0, 0.0);
compositeOpacity->AddPoint(700.0, 0.0);
compositeOpacity->AddPoint(3600.0, 1.0);
volumeProperty->SetScalarOpacity(compositeOpacity); // composite first.
vtkSmartPointer<vtkColorTransferFunction> color = vtkSmartPointer<vtkColorTransferFunction>::New();
color->AddRGBPoint(0.0, 1.0, 0.0, 0.0);
color->AddRGBPoint(3600.0, 1.0, 0.0, 1.0);
volumeProperty->SetColor(color);
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
// Renderer
mRenderer->AddActor(sphereActor);
mRenderer->AddVolume(volume);
mRenderer->ResetCamera();
// axes
vtkAxesActor *axes = vtkAxesActor::New();
vtkOrientationMarkerWidget *widget = vtkOrientationMarkerWidget::New();
widget->SetDefaultRenderer(mRenderer);
widget->SetOrientationMarker(axes);
widget->SetInteractor(mQVTKWidget->GetRenderWindow()->GetInteractor());
widget->EnabledOn();
vtkSmartPointer<vtkCubeAxesActor> cubeAxesActor =
vtkSmartPointer<vtkCubeAxesActor>::New();
cubeAxesActor->SetBounds(volume->GetBounds());
cubeAxesActor->SetCamera(mRenderer->GetActiveCamera());
mRenderer->AddActor(cubeAxesActor);
}
[编辑]
这是输出的屏幕截图:
我做错了什么?
与 here 中的代码示例进行比较后,我找到了解决方案。错误不在问题的代码片段中,而是在 main() where:
QSurfaceFormat::setDefaultFormat(QVTKOpenGLWidget::defaultFormat());
应替换为:
auto defaultFormat = QVTKOpenGLWidget::defaultFormat();
defaultFormat.setSamples(0);
QSurfaceFormat::setDefaultFormat(defaultFormat);
VTK bug tracker issue #17095 中也讨论了这个问题。