VTK9.2.0+QT5.14.0绘制三维显示背景

背景

上一篇绘制点云的博文中,使用的vtkCameraOrientationWidget来绘制的坐标轴,最近又学习到两种新的坐标轴绘制形式。

vtkOrientationMarkerWidget + vtkAxesActor

单独使用vtkAxesActor能够绘制出坐标轴,但是会随着鼠标操作旋转和平移时,在三维窗口中移动。搭配vtkOrientationMarkerWidget 的话能够在三维窗口的widget中,再放置一个小的widget,专门放置vtkAxesActor,可以达到停留在窗口左下角,只随着鼠标旋转的目的。

在头文件中定义vtkOrientationMarkerWidget 的对象

	vtkSmartPointer<vtkOrientationMarkerWidget> markerOrientationWidget;
void QVtkDemo2::testVtk3D()
{
	//创建着色器对象
	vtkSmartPointer<vtkRenderer> g_vtkRenderer = vtkSmartPointer<vtkRenderer>::New();
	//设置背景颜色
	g_vtkRenderer->SetBackground(.1, .2, .4);
	//创建point对象
	vtkSmartPointer<vtkPoints> g_vtkPoints = vtkSmartPointer<vtkPoints>::New();
	g_vtkPoints->SetNumberOfPoints(200);
	//创建cell对象
	vtkSmartPointer<vtkCellArray> g_vtkVertices = vtkSmartPointer<vtkCellArray>::New();
	vtkIdType id[1];
	//随机生成200个点
	float minz = VTK_FLOAT_MAX, maxz = VTK_FLOAT_MIN;
	for (int i = 0; i < 200; i++)
	{
		float x = rand() % 10;
		float y = rand() % 10;
		float z = rand() % 10;
		//提前申请了points的数量,使用set比insert速度更快
		g_vtkPoints->SetPoint(i, x, y, z);
		id[0] = i;
		g_vtkVertices->InsertNextCell(1, id);
		if (z > maxz)
		{
			maxz = z;
		}
		if (z < minz)
		{
			minz = z;
		}
	}
	//创建poly对象
	vtkSmartPointer<vtkPolyData> g_vtkpolyData = vtkSmartPointer<vtkPolyData>::New();
	g_vtkpolyData->SetPoints(g_vtkPoints);
	g_vtkpolyData->SetVerts(g_vtkVertices);

	vtkSmartPointer<vtkVertexGlyphFilter> g_glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
	g_glyphFilter->SetInputData(g_vtkpolyData);
	g_glyphFilter->Update();

	vtkSmartPointer<vtkElevationFilter> g_elevationFilter = vtkSmartPointer<vtkElevationFilter>::New();
	g_elevationFilter->SetInputConnection(g_glyphFilter->GetOutputPort());
	g_elevationFilter->SetLowPoint(0, 0, minz);
	g_elevationFilter->SetHighPoint(0, 0, maxz);

	//创建polyMapper
	vtkSmartPointer<vtkPolyDataMapper> g_vtkpointsMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	g_vtkpointsMapper->SetInputConnection(g_elevationFilter->GetOutputPort());

	//创建Actor
	vtkSmartPointer<vtkActor> g_vtkpointsActor = vtkSmartPointer<vtkActor>::New();
	g_vtkpointsActor->SetMapper(g_vtkpointsMapper);
	g_vtkpointsActor->GetProperty()->SetPointSize(3);//设置点的大小
	g_vtkRenderer->AddActor(g_vtkpointsActor);

	vtkNew<vtkLookupTable> lut = vtkNew<vtkLookupTable>::vtkNew();
	lut->SetNumberOfTableValues(7);
	lut->SetHueRange(0.0, 0.67);
	lut->SetTableRange(minz, maxz);
	lut->Build();

	vtkNew<vtkScalarBarActor> colorBar = vtkNew<vtkScalarBarActor>::vtkNew();
	colorBar->SetLookupTable(lut);
	colorBar->SetNumberOfLabels(7);
	colorBar->SetBarRatio(0.10);
	colorBar->SetUnconstrainedFontSize(0.05);
	colorBar->SetMaximumHeightInPixels(100);
	colorBar->SetDisplayPosition(500, 80);
	g_vtkRenderer->AddActor2D(colorBar);

	//根据点云的包围盒,寻找最佳的显示视点位置
	g_vtkRenderer->ResetCamera();
	//ui中的绘制窗口添加定义的着色器
	ui.openGLWidget->renderWindow()->AddRenderer(g_vtkRenderer);
	//开始三维渲染
	ui.openGLWidget->renderWindow()->Render();

	//绘制坐标轴
	vtkSmartPointer<vtkAxesActor> axes_actor = vtkSmartPointer<vtkAxesActor>::New();
	axes_actor->SetPosition(0, 0, 0);
	axes_actor->SetTotalLength(50, 50, 50);
	//axes_actor->SetScale(5.0);
	//axes_actor->SetShaftType(0);
	//axes_actor->SetCylinderRadius(0.1);
	//axes_actor->SetConeRadius(0.3);
	//axes_actor->SetAxisLabels(1);
	//axes_actor->SetTipType(0); //坐标轴顶部为圆锥体
	axes_actor->GetXAxisShaftProperty()->SetColor(1, 0, 1);
	axes_actor->GetXAxisTipProperty()->SetColor(1, 0, 1);

	axes_actor->GetZAxisShaftProperty()->SetColor(1, 1, 0);
	axes_actor->GetZAxisTipProperty()->SetColor(1, 1, 0);

	markerOrientationWidget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
	markerOrientationWidget->SetOrientationMarker(axes_actor);
	markerOrientationWidget->SetInteractor(ui.openGLWidget->interactor());
	markerOrientationWidget->SetCurrentRenderer(g_vtkRenderer);
	markerOrientationWidget->SetDefaultRenderer(g_vtkRenderer);
	markerOrientationWidget->SetViewport(0.0, 0.0, 0.2, 0.2);
	markerOrientationWidget->SetEnabled(1);
	markerOrientationWidget->SetZoom(1.2);
	markerOrientationWidget->SetInteractive(false);

	return;
}

在这里插入图片描述
可以为三维空间添加一个网格底面,如图所示
在这里插入图片描述
只需要在上述代码中,创建一个新的Actor以及对应的Mapper和PlaneSource,然后向renderer中添加一个额外的Actor,并通过vtkCamera来设定我们当前的视角,提升观感

void QVtkDemo2::testVtk3D()
{
	//创建着色器对象
	vtkSmartPointer<vtkRenderer> g_vtkRenderer = vtkSmartPointer<vtkRenderer>::New();
	//设置背景颜色
	g_vtkRenderer->SetBackground(.1, .2, .4);
	//创建point对象
	vtkSmartPointer<vtkPoints> g_vtkPoints = vtkSmartPointer<vtkPoints>::New();
	g_vtkPoints->SetNumberOfPoints(200);
	//创建cell对象
	vtkSmartPointer<vtkCellArray> g_vtkVertices = vtkSmartPointer<vtkCellArray>::New();
	vtkIdType id[1];
	//随机生成200个点
	float minz = VTK_FLOAT_MAX, maxz = VTK_FLOAT_MIN;
	for (int i = 0; i < 200; i++)
	{
		float x = rand() % 10;
		float y = rand() % 10;
		float z = rand() % 10;
		//提前申请了points的数量,使用set比insert速度更快
		g_vtkPoints->SetPoint(i, x, y, z);
		id[0] = i;
		g_vtkVertices->InsertNextCell(1, id);
		if (z > maxz)
		{
			maxz = z;
		}
		if (z < minz)
		{
			minz = z;
		}
	}
	//创建poly对象
	vtkSmartPointer<vtkPolyData> g_vtkpolyData = vtkSmartPointer<vtkPolyData>::New();
	g_vtkpolyData->SetPoints(g_vtkPoints);
	g_vtkpolyData->SetVerts(g_vtkVertices);

	vtkSmartPointer<vtkVertexGlyphFilter> g_glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
	g_glyphFilter->SetInputData(g_vtkpolyData);
	g_glyphFilter->Update();

	vtkSmartPointer<vtkElevationFilter> g_elevationFilter = vtkSmartPointer<vtkElevationFilter>::New();
	g_elevationFilter->SetInputConnection(g_glyphFilter->GetOutputPort());
	g_elevationFilter->SetLowPoint(0, 0, minz);
	g_elevationFilter->SetHighPoint(0, 0, maxz);

	//创建polyMapper
	vtkSmartPointer<vtkPolyDataMapper> g_vtkpointsMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	g_vtkpointsMapper->SetInputConnection(g_elevationFilter->GetOutputPort());

	//创建Actor
	vtkSmartPointer<vtkActor> g_vtkpointsActor = vtkSmartPointer<vtkActor>::New();
	g_vtkpointsActor->SetMapper(g_vtkpointsMapper);
	g_vtkpointsActor->GetProperty()->SetPointSize(3);//设置点的大小
	g_vtkRenderer->AddActor(g_vtkpointsActor);

	vtkNew<vtkLookupTable> lut = vtkNew<vtkLookupTable>::vtkNew();
	lut->SetNumberOfTableValues(7);
	lut->SetHueRange(0.0, 0.67);
	lut->SetTableRange(minz, maxz);
	lut->Build();

	vtkNew<vtkScalarBarActor> colorBar = vtkNew<vtkScalarBarActor>::vtkNew();
	colorBar->SetLookupTable(lut);
	colorBar->SetNumberOfLabels(7);
	colorBar->SetBarRatio(0.10);
	colorBar->SetUnconstrainedFontSize(0.05);
	colorBar->SetMaximumHeightInPixels(100);
	colorBar->SetDisplayPosition(500, 80);
	g_vtkRenderer->AddActor2D(colorBar);

	//定义一个平面
	vtkSmartPointer<vtkPlaneSource> mReferencePlaneSource;
	vtkSmartPointer<vtkPolyDataMapper> mReferencePlaneMapper;
	vtkSmartPointer<vtkActor>  mReferencePlaneActor;

	//添加平面
	mReferencePlaneSource = vtkSmartPointer<vtkPlaneSource>::New();
	mReferencePlaneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	mReferencePlaneActor = vtkSmartPointer<vtkActor>::New();
	mReferencePlaneSource->SetXResolution(20);
	mReferencePlaneSource->SetYResolution(20);
	mReferencePlaneSource->SetOrigin(-10.0, -10.0, -6.0); //根据视野范围来调整
	mReferencePlaneSource->SetPoint1(10.0, -10.0, -6.0);
	mReferencePlaneSource->SetPoint2(-10.0, 10.0, -6.0);
	mReferencePlaneMapper->SetInputConnection(mReferencePlaneSource->GetOutputPort());
	mReferencePlaneActor->SetMapper(mReferencePlaneMapper);
	mReferencePlaneActor->GetProperty()->SetRepresentationToWireframe();
	mReferencePlaneActor->GetProperty()->SetColor(0.5, 1.0, 1.0);
	mReferencePlaneActor->SetVisibility(true);
	g_vtkRenderer->AddActor(mReferencePlaneActor);
	vtkSmartPointer<vtkCamera> _vtk_icamera = vtkSmartPointer<vtkCamera>::New();
	_vtk_icamera->SetPosition(50.0, 50.0, 30.0);
	_vtk_icamera->SetFocalPoint(0.0, 0.0, 0.0);
	_vtk_icamera->SetViewUp(0.0, 0.0, 1.0);
	_vtk_icamera->ComputeViewPlaneNormal();
	if (_vtk_icamera)
	{
		g_vtkRenderer->SetActiveCamera(_vtk_icamera);
		g_vtkRenderer->ResetCamera();
	}

	//根据点云的包围盒,寻找最佳的显示视点位置
	//g_vtkRenderer->ResetCamera();
	//ui中的绘制窗口添加定义的着色器
	ui.openGLWidget->renderWindow()->AddRenderer(g_vtkRenderer);
	//开始三维渲染
	ui.openGLWidget->renderWindow()->Render();

	//绘制坐标轴
	vtkSmartPointer<vtkAxesActor> axes_actor = vtkSmartPointer<vtkAxesActor>::New();
	axes_actor->SetPosition(0, 0, 0);
	axes_actor->SetTotalLength(50, 50, 50);
	//axes_actor->SetScale(5.0);
	//axes_actor->SetShaftType(0);
	//axes_actor->SetCylinderRadius(0.1);
	//axes_actor->SetConeRadius(0.3);
	//axes_actor->SetAxisLabels(1);
	//axes_actor->SetTipType(0); //坐标轴顶部为圆锥体
	axes_actor->GetXAxisShaftProperty()->SetColor(1, 0, 1);
	axes_actor->GetXAxisTipProperty()->SetColor(1, 0, 1);

	axes_actor->GetZAxisShaftProperty()->SetColor(1, 1, 0);
	axes_actor->GetZAxisTipProperty()->SetColor(1, 1, 0);

	markerOrientationWidget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
	markerOrientationWidget->SetOrientationMarker(axes_actor);
	markerOrientationWidget->SetInteractor(ui.openGLWidget->interactor());
	markerOrientationWidget->SetCurrentRenderer(g_vtkRenderer);
	markerOrientationWidget->SetDefaultRenderer(g_vtkRenderer);
	markerOrientationWidget->SetViewport(0.0, 0.0, 0.2, 0.2);
	markerOrientationWidget->SetEnabled(1);
	markerOrientationWidget->SetZoom(1.2);
	markerOrientationWidget->SetInteractive(false);

	return;
}

vtkCubeAxesActor

下图是matlab的三维显示,想要绘制网格状的坐标轴,并标注坐标,VTK提供了vtkCubeAxesActor
在这里插入图片描述
vtkCubeAxesActor作为一类Actor, 因此,我们只需要定义好vtkCubeAxesActor的参数,然后添加到Renderer中即可

void QVtkDemo2::testVtk3D()
{
	//创建着色器对象
	vtkSmartPointer<vtkRenderer> g_vtkRenderer = vtkSmartPointer<vtkRenderer>::New();
	//设置背景颜色
	g_vtkRenderer->SetBackground(.1, .2, .4);
	//创建point对象
	vtkSmartPointer<vtkPoints> g_vtkPoints = vtkSmartPointer<vtkPoints>::New();
	g_vtkPoints->SetNumberOfPoints(200);
	//创建cell对象
	vtkSmartPointer<vtkCellArray> g_vtkVertices = vtkSmartPointer<vtkCellArray>::New();
	vtkIdType id[1];
	//随机生成200个点
	float minz = VTK_FLOAT_MAX, maxz = VTK_FLOAT_MIN;
	for (int i = 0; i < 200; i++)
	{
		float x = rand() % 10;
		float y = rand() % 10;
		float z = rand() % 10;
		//提前申请了points的数量,使用set比insert速度更快
		g_vtkPoints->SetPoint(i, x, y, z);
		id[0] = i;
		g_vtkVertices->InsertNextCell(1, id);
		if (z > maxz)
		{
			maxz = z;
		}
		if (z < minz)
		{
			minz = z;
		}
	}
	//创建poly对象
	vtkSmartPointer<vtkPolyData> g_vtkpolyData = vtkSmartPointer<vtkPolyData>::New();
	g_vtkpolyData->SetPoints(g_vtkPoints);
	g_vtkpolyData->SetVerts(g_vtkVertices);

	vtkSmartPointer<vtkVertexGlyphFilter> g_glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
	g_glyphFilter->SetInputData(g_vtkpolyData);
	g_glyphFilter->Update();

	vtkSmartPointer<vtkElevationFilter> g_elevationFilter = vtkSmartPointer<vtkElevationFilter>::New();
	g_elevationFilter->SetInputConnection(g_glyphFilter->GetOutputPort());
	g_elevationFilter->SetLowPoint(0, 0, minz);
	g_elevationFilter->SetHighPoint(0, 0, maxz);

	//创建polyMapper
	vtkSmartPointer<vtkPolyDataMapper> g_vtkpointsMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	g_vtkpointsMapper->SetInputConnection(g_elevationFilter->GetOutputPort());

	//创建Actor
	vtkSmartPointer<vtkActor> g_vtkpointsActor = vtkSmartPointer<vtkActor>::New();
	g_vtkpointsActor->SetMapper(g_vtkpointsMapper);
	g_vtkpointsActor->GetProperty()->SetPointSize(3);//设置点的大小
	g_vtkRenderer->AddActor(g_vtkpointsActor);

	vtkNew<vtkLookupTable> lut = vtkNew<vtkLookupTable>::vtkNew();
	lut->SetNumberOfTableValues(7);
	lut->SetHueRange(0.0, 0.67);
	lut->SetTableRange(minz, maxz);
	lut->Build();

	vtkNew<vtkScalarBarActor> colorBar = vtkNew<vtkScalarBarActor>::vtkNew();
	colorBar->SetLookupTable(lut);
	colorBar->SetNumberOfLabels(7);
	colorBar->SetBarRatio(0.10);
	colorBar->SetUnconstrainedFontSize(0.05);
	colorBar->SetMaximumHeightInPixels(100);
	colorBar->SetDisplayPosition(500, 80);
	g_vtkRenderer->AddActor2D(colorBar);

	//vtkCubeAxes
	vtkSmartPointer<vtkCubeAxesActor> cubeAxes = vtkSmartPointer<vtkCubeAxesActor>::New();
	auto activeCamera = g_vtkRenderer->GetActiveCamera();
	cubeAxes->SetCamera(activeCamera);

	double bounds[6] = { 0.0, 10.0, 0.0, 10.0, 0.0, 10.0 };
	cubeAxes->SetBounds(bounds);

	cubeAxes->SetXTitle("X-Axis");
	cubeAxes->SetYTitle("Y-Axis");
	cubeAxes->SetZTitle("Z-Axis");

	cubeAxes->GetTitleTextProperty(0)->SetColor(1.0, 0.0, 1.0);
	cubeAxes->GetLabelTextProperty(0)->SetColor(1.0, 0.0, 1.0);

	cubeAxes->GetTitleTextProperty(1)->SetColor(0.0, 1.0, 0.0);
	cubeAxes->GetLabelTextProperty(1)->SetColor(0.0, 1.0, 0.0);

	cubeAxes->GetTitleTextProperty(2)->SetColor(1.0, 1.0, 0.0);
	cubeAxes->GetLabelTextProperty(2)->SetColor(1.0, 1.0, 0.0);

	cubeAxes->SetVisibility(1);

	cubeAxes->SetXAxisRange(0, 10.0);
	cubeAxes->SetYAxisRange(0.0, 10.0);
	cubeAxes->SetZAxisRange(0.0, 10.0);

	cubeAxes->DrawXGridlinesOn();
	cubeAxes->DrawYGridlinesOn();
	cubeAxes->DrawZGridlinesOn();
	cubeAxes->SetDrawXInnerGridlines(0);
	cubeAxes->SetDrawYInnerGridlines(0);
	cubeAxes->SetDrawZInnerGridlines(0);

	cubeAxes->XAxisMinorTickVisibilityOff();
	cubeAxes->YAxisMinorTickVisibilityOff();
	cubeAxes->ZAxisMinorTickVisibilityOff();

	cubeAxes->SetScreenSize(30.0);
	cubeAxes->SetLabelOffset(20.0);

	cubeAxes->SetGridLineLocation(2);
	cubeAxes->SetTickLocation(1);
	cubeAxes->SetFlyMode(0);
	g_vtkRenderer->AddActor(cubeAxes);


	vtkSmartPointer<vtkCamera> _vtk_icamera = vtkSmartPointer<vtkCamera>::New();
	_vtk_icamera->SetPosition(50.0, 50.0, 30.0);
	_vtk_icamera->SetFocalPoint(0.0, 0.0, 0.0);
	_vtk_icamera->SetViewUp(0.0, 0.0, 1.0);
	_vtk_icamera->ComputeViewPlaneNormal();
	if (_vtk_icamera)
	{
		g_vtkRenderer->SetActiveCamera(_vtk_icamera);
		g_vtkRenderer->ResetCamera();
	}

	//根据点云的包围盒,寻找最佳的显示视点位置
	//g_vtkRenderer->ResetCamera();
	//ui中的绘制窗口添加定义的着色器
	ui.openGLWidget->renderWindow()->AddRenderer(g_vtkRenderer);
	//开始三维渲染
	ui.openGLWidget->renderWindow()->Render();

	//绘制坐标轴
	vtkSmartPointer<vtkAxesActor> axes_actor = vtkSmartPointer<vtkAxesActor>::New();
	axes_actor->SetPosition(0, 0, 0);
	axes_actor->SetTotalLength(50, 50, 50);
	//axes_actor->SetScale(5.0);
	//axes_actor->SetShaftType(0);
	//axes_actor->SetCylinderRadius(0.1);
	//axes_actor->SetConeRadius(0.3);
	//axes_actor->SetAxisLabels(1);
	//axes_actor->SetTipType(0); //坐标轴顶部为圆锥体
	axes_actor->GetXAxisShaftProperty()->SetColor(1, 0, 1);
	axes_actor->GetXAxisTipProperty()->SetColor(1, 0, 1);

	axes_actor->GetZAxisShaftProperty()->SetColor(1, 1, 0);
	axes_actor->GetZAxisTipProperty()->SetColor(1, 1, 0);

	markerOrientationWidget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
	markerOrientationWidget->SetOrientationMarker(axes_actor);
	markerOrientationWidget->SetInteractor(ui.openGLWidget->interactor());
	markerOrientationWidget->SetCurrentRenderer(g_vtkRenderer);
	markerOrientationWidget->SetDefaultRenderer(g_vtkRenderer);
	markerOrientationWidget->SetViewport(0.0, 0.0, 0.2, 0.2);
	markerOrientationWidget->SetEnabled(1);
	markerOrientationWidget->SetZoom(1.2);
	markerOrientationWidget->SetInteractive(false);

	
	return;
}

在这里插入图片描述

带灰度纹理点云的三维显示

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

leaf_csdn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值