VTK 的可视化方法:Cutting & Probing

VTK 的可视化方法:Cutting & Probing

VTK 的可视化方法:Cutting & Probing

Cutting 和 Probing 都是对三维数据截取二维平面的方法。它们的区别是:

  1. Cutting 使用 vtkCutter 类,采用隐式函数截取数据; Probing使用 vtkProbeFilter 类,利用另一个数据来截取数据,或者说采样。
  2. Cutting 截面的大小依据原数据集;Probing 截取数据的大小等于数据截面的大小。
  3. Cutting 截面的分辨率等于原数据集的分辨率,网格也是原数据的网格;Probing 截面的分辨率和网格与数据截面相同,可以自定义。

Cutting

采用vtkCutter类做截取,设置截取平面隐函数cuttingPlane和范围range,即可等间距截取二维平面。

#include "VTKCuttingAndProbing.h"

#include <vtkConeSource.h>
#include <vtkSTLReader.h>
#include <vtkMultiBlockPLOT3DReader.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkDataSet.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkShrinkPolyData.h>
#include <vtkStructuredGridGeometryFilter.h>
#include <vtkStructuredGridOutlineFilter.h>
#include <vtkLookupTable.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>

VTKCuttingAndProbing::VTKCuttingAndProbing(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	_pVTKWidget = new QVTKOpenGLNativeWidget();
	this->setCentralWidget(_pVTKWidget);
	// this->showMaximized();

	// 1. generate data
	// vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
	// or, read data
	// vtkMultiBlockPLOT3DReader 是一个读取器对象,用于读取 PLOT3D 格式的文件并在输出时生成结构化网格
	vtkSmartPointer<vtkMultiBlockPLOT3DReader> plot3dReader = vtkSmartPointer<vtkMultiBlockPLOT3DReader>::New();
	plot3dReader->SetXYZFileName("combxyz.bin");
	plot3dReader->SetQFileName("combq.bin");
	plot3dReader->SetScalarFunctionNumber(100);
	plot3dReader->SetVectorFunctionNumber(202);
	qDebug() << plot3dReader->GetOutput()->GetNumberOfBlocks(); // 0
	// 反向更新管线
	plot3dReader->Update();
	qDebug() << plot3dReader->GetOutput()->GetNumberOfBlocks(); // 1
	vtkDataSet* plot3dOutput = (vtkDataSet*)(plot3dReader->GetOutput()->GetBlock(0));

	vtkSmartPointer<vtkPlane> cuttingPlane = vtkSmartPointer<vtkPlane>::New();
	// 设置中心
	cuttingPlane->SetOrigin(plot3dOutput->GetCenter());
	// 设置法向量
	cuttingPlane->SetNormal(1, 0, 0.3);

	vtkSmartPointer<vtkCutter> planeCut = vtkSmartPointer<vtkCutter>::New();
	planeCut->SetInputData(plot3dOutput);
	// 设置截取平面隐函数
	planeCut->SetCutFunction(cuttingPlane);
	double range[2] = { -5, 5 };
	planeCut->GenerateValues(3, range);

	// 2. filter
	// 提取作为多边形几何(点,线,表面)的栅格的一部分
	vtkSmartPointer<vtkStructuredGridGeometryFilter> plane = vtkSmartPointer<vtkStructuredGridGeometryFilter>::New();
	plane->SetInputData(plot3dOutput);
	plane->SetExtent(1, 100, 1, 100, 7, 7);
	// 产生结构化栅格边界的一个线轮廓
	vtkSmartPointer<vtkStructuredGridOutlineFilter> outline = vtkSmartPointer<vtkStructuredGridOutlineFilter>::New();
	outline->SetInputData(plot3dOutput);
	// 颜色映射表
	vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
	lut->SetNumberOfColors(256); // 指定颜色映射表中有多少种颜色
	lut->Build();

	// 3. mapper
	vtkSmartPointer<vtkPolyDataMapper> planeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkPolyDataMapper> outlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkPolyDataMapper> cuttingMapper = vtkSmartPointer<vtkPolyDataMapper>::New();

	// 4. actor
	vtkSmartPointer<vtkActor> planeActor = vtkSmartPointer<vtkActor>::New();
	vtkSmartPointer<vtkActor> outlineActor = vtkSmartPointer<vtkActor>::New();
	vtkSmartPointer<vtkActor> cuttingActor = vtkSmartPointer<vtkActor>::New();

	// 5. renderer
	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
	renderer->SetBackground(0.3, 0.6, 0.3); // Background Color: Green

	// 6. connect
	planeMapper->SetLookupTable(lut);
	planeMapper->SetInputConnection(plane->GetOutputPort());
	planeMapper->SetScalarRange(plot3dOutput->GetScalarRange()); // 设置标量值的范围
	outlineMapper->SetInputConnection(outline->GetOutputPort());
	cuttingMapper->SetInputConnection(planeCut->GetOutputPort());
	cuttingMapper->SetScalarRange(plot3dOutput->GetScalarRange()); // 设置标量值的范围
	planeActor->SetMapper(planeMapper);
	outlineActor->SetMapper(outlineMapper);
	cuttingActor->SetMapper(cuttingMapper);
	// renderer->AddActor(planeActor);
	renderer->AddActor(outlineActor);
	renderer->AddActor(cuttingActor);

	this->_pVTKWidget->renderWindow()->AddRenderer(renderer);
	this->_pVTKWidget->renderWindow()->Render();
}

VTKCuttingAndProbing::~VTKCuttingAndProbing()
{}

运行结果:

在这里插入图片描述

按W键切换成网格模式:

在这里插入图片描述

Probing

#include "VTKCuttingAndProbing.h"

#include <vtkConeSource.h>
#include <vtkPlaneSource.h>
#include <vtkSTLReader.h>
#include <vtkMultiBlockPLOT3DReader.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkTransform.h>
#include <vtkDataSet.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkStructuredGridGeometryFilter.h>
#include <vtkOutlineFilter.h>
#include <vtkStructuredGridOutlineFilter.h>
#include <vtkProbeFilter.h>
#include <vtkLookupTable.h>
#include <vtkPolyDataMapper.h>
#include <vtkAppendPolyData.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>

VTKCuttingAndProbing::VTKCuttingAndProbing(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	_pVTKWidget = new QVTKOpenGLNativeWidget();
	this->setCentralWidget(_pVTKWidget);
	// this->showMaximized();

	// 1. generate data
	// vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
	// or, read data
	// vtkMultiBlockPLOT3DReader 是一个读取器对象,用于读取 PLOT3D 格式的文件并在输出时生成结构化网格
	vtkSmartPointer<vtkMultiBlockPLOT3DReader> plot3dReader = vtkSmartPointer<vtkMultiBlockPLOT3DReader>::New();
	plot3dReader->SetXYZFileName("combxyz.bin");
	plot3dReader->SetQFileName("combq.bin");
	plot3dReader->SetScalarFunctionNumber(100);
	plot3dReader->SetVectorFunctionNumber(202);
	qDebug() << plot3dReader->GetOutput()->GetNumberOfBlocks(); // 0
	// 反向更新管线
	plot3dReader->Update();
	qDebug() << plot3dReader->GetOutput()->GetNumberOfBlocks(); // 1
	vtkDataSet* plot3dOutput = (vtkDataSet*)(plot3dReader->GetOutput()->GetBlock(0));

	// Cutting
	vtkSmartPointer<vtkPlane> cuttingPlane = vtkSmartPointer<vtkPlane>::New();
	// 设置中心
	cuttingPlane->SetOrigin(plot3dOutput->GetCenter());
	// 设置法向量
	cuttingPlane->SetNormal(1, 0, 0.3);
	vtkSmartPointer<vtkCutter> planeCut = vtkSmartPointer<vtkCutter>::New();
	planeCut->SetInputData(plot3dOutput);
	// 设置截取平面隐函数
	planeCut->SetCutFunction(cuttingPlane);
	double range[2] = { -5, 5 };
	planeCut->GenerateValues(3, range);

	// 截面数据
	vtkSmartPointer<vtkPlaneSource> probePlane = vtkSmartPointer<vtkPlaneSource>::New();
	probePlane->SetResolution(50, 50);

	// 对于一个数据,我们需要坐标变换才能移动它的位置
	vtkSmartPointer<vtkTransform> transform1 = vtkSmartPointer<vtkTransform>::New();
	transform1->Translate(3.7, 0, 28.37);
	transform1->Scale(5, 5, 5);
	transform1->RotateY(90);

	vtkSmartPointer<vtkTransform> transform2 = vtkSmartPointer<vtkTransform>::New();
	transform2->Translate(9.2, 0, 31.2);
	transform2->Scale(5, 5, 5);
	transform2->RotateY(90);

	vtkSmartPointer<vtkTransform> transform3 = vtkSmartPointer<vtkTransform>::New();
	transform3->Translate(13.27, 0, 33.3);
	transform3->Scale(5, 5, 5);
	transform3->RotateY(90);

	// 2. filter
	// 提取作为多边形几何(点,线,表面)的栅格的一部分
	vtkSmartPointer<vtkStructuredGridGeometryFilter> plane = vtkSmartPointer<vtkStructuredGridGeometryFilter>::New();
	plane->SetInputData(plot3dOutput);
	plane->SetExtent(1, 100, 1, 100, 7, 7);
	// 产生结构化栅格边界的一个线轮廓
	vtkSmartPointer<vtkStructuredGridOutlineFilter> outline = vtkSmartPointer<vtkStructuredGridOutlineFilter>::New();
	outline->SetInputData(plot3dOutput);
	// 颜色映射表
	vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
	lut->SetNumberOfColors(256); // 指定颜色映射表中有多少种颜色
	lut->Build();

	// 截面 1
	vtkSmartPointer<vtkTransformPolyDataFilter> tpd1Filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
	tpd1Filter->SetInputConnection(probePlane->GetOutputPort());
	tpd1Filter->SetTransform(transform1); // 坐标变换
	// 截面 1 的 outline
	vtkSmartPointer<vtkOutlineFilter> outlineTpd1 = vtkSmartPointer<vtkOutlineFilter>::New();
	outlineTpd1->SetInputConnection(tpd1Filter->GetOutputPort());
	// 截面 2
	vtkSmartPointer<vtkTransformPolyDataFilter> tpd2Filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
	tpd2Filter->SetInputConnection(probePlane->GetOutputPort());
	tpd2Filter->SetTransform(transform2); // 坐标变换
	// 截面 2 的 outline
	vtkSmartPointer<vtkOutlineFilter> outlineTpd2 = vtkSmartPointer<vtkOutlineFilter>::New();
	outlineTpd2->SetInputConnection(tpd2Filter->GetOutputPort());
	// 截面 3
	vtkSmartPointer<vtkTransformPolyDataFilter> tpd3Filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
	tpd3Filter->SetInputConnection(probePlane->GetOutputPort());
	tpd3Filter->SetTransform(transform3); // 坐标变换
	// 截面 3 的 outline
	vtkSmartPointer<vtkOutlineFilter> outlineTpd3 = vtkSmartPointer<vtkOutlineFilter>::New();
	outlineTpd3->SetInputConnection(tpd3Filter->GetOutputPort());
	// 截面集合
	vtkSmartPointer<vtkAppendPolyData> append = vtkSmartPointer<vtkAppendPolyData>::New();
	append->AddInputConnection(tpd1Filter->GetOutputPort());
	append->AddInputConnection(tpd2Filter->GetOutputPort());
	append->AddInputConnection(tpd3Filter->GetOutputPort());
	// Probe
	vtkSmartPointer<vtkProbeFilter> probeFilter = vtkSmartPointer<vtkProbeFilter>::New();
	probeFilter->SetInputConnection(append->GetOutputPort());
	probeFilter->SetSourceData(plot3dOutput);

	// 3. mapper
	vtkSmartPointer<vtkPolyDataMapper> planeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkPolyDataMapper> outlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkPolyDataMapper> cuttingMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkPolyDataMapper> outlineTpd1Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkPolyDataMapper> outlineTpd2Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkPolyDataMapper> outlineTpd3Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkPolyDataMapper> probeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();

	// 4. actor
	vtkSmartPointer<vtkActor> planeActor = vtkSmartPointer<vtkActor>::New();
	vtkSmartPointer<vtkActor> outlineActor = vtkSmartPointer<vtkActor>::New();
	vtkSmartPointer<vtkActor> cuttingActor = vtkSmartPointer<vtkActor>::New();
	vtkSmartPointer<vtkActor> outlineTpd1Actor = vtkSmartPointer<vtkActor>::New();
	vtkSmartPointer<vtkActor> outlineTpd2Actor = vtkSmartPointer<vtkActor>::New();
	vtkSmartPointer<vtkActor> outlineTpd3Actor = vtkSmartPointer<vtkActor>::New();
	vtkSmartPointer<vtkActor> probeActor = vtkSmartPointer<vtkActor>::New();

	// 5. renderer
	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
	renderer->SetBackground(0.3, 0.6, 0.3); // Background Color: Green

	// 6. connect
	planeMapper->SetLookupTable(lut);
	planeMapper->SetInputConnection(plane->GetOutputPort());
	planeMapper->SetScalarRange(plot3dOutput->GetScalarRange()); // 设置标量值的范围
	outlineMapper->SetInputConnection(outline->GetOutputPort());
	cuttingMapper->SetInputConnection(planeCut->GetOutputPort());
	cuttingMapper->SetScalarRange(plot3dOutput->GetScalarRange()); // 设置标量值的范围
	outlineTpd1Mapper->SetInputConnection(outlineTpd1->GetOutputPort());
	outlineTpd2Mapper->SetInputConnection(outlineTpd2->GetOutputPort());
	outlineTpd3Mapper->SetInputConnection(outlineTpd3->GetOutputPort());
	probeMapper->SetInputConnection(probeFilter->GetOutputPort());
	probeMapper->SetScalarRange(plot3dOutput->GetScalarRange()); // 设置标量值的范围
	planeActor->SetMapper(planeMapper);
	outlineActor->SetMapper(outlineMapper);
	cuttingActor->SetMapper(cuttingMapper);
	outlineTpd1Actor->SetMapper(outlineTpd1Mapper);
	outlineTpd2Actor->SetMapper(outlineTpd2Mapper);
	outlineTpd3Actor->SetMapper(outlineTpd3Mapper);
	probeActor->SetMapper(probeMapper);
	// renderer->AddActor(planeActor);
	renderer->AddActor(outlineActor);
	// renderer->AddActor(cuttingActor);
	renderer->AddActor(outlineTpd1Actor);
	renderer->AddActor(outlineTpd2Actor);
	renderer->AddActor(outlineTpd3Actor);
	renderer->AddActor(probeActor);

	this->_pVTKWidget->renderWindow()->AddRenderer(renderer);
	this->_pVTKWidget->renderWindow()->Render();
}

VTKCuttingAndProbing::~VTKCuttingAndProbing()
{}

运行结果:

在这里插入图片描述

按W键切换成网格模式,可以看出分辨率为50*50:

在这里插入图片描述

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值