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

背景

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

vtkOrientationMarkerWidget + vtkAxesActor

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

在头文件中定义vtkOrientationMarkerWidget 的对象

cpp 复制代码
	vtkSmartPointer<vtkOrientationMarkerWidget> markerOrientationWidget;
cpp 复制代码
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来设定我们当前的视角,提升观感

cpp 复制代码
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中即可

cpp 复制代码
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;
}

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

相关推荐
做怪小疯子21 分钟前
JavaScript 中Array 整理
开发语言·前端·javascript
旭编21 分钟前
牛客周赛 Round 117
java·开发语言
六元七角八分28 分钟前
CSDN文章如何转出为PDF文件保存
开发语言·javascript·pdf
froginwe1135 分钟前
MongoDB 删除数据库
开发语言
Java小混子36 分钟前
golang项目CRUD示例
开发语言·后端·golang
想搞艺术的程序员39 分钟前
Go 优雅关闭实践指南:从原理到框架落地
开发语言·后端·golang
m5655bj44 分钟前
Python 查找并高亮显示指定 Excel 数据
开发语言·python·excel
洛克希德马丁1 小时前
Qt 配置Webassemble环境
开发语言·qt·webassembly·emscripten·emsdk
武子康1 小时前
Java-167 Neo4j CQL 实战:CREATE/MATCH 与关系建模速通 案例实测
java·开发语言·数据库·python·sql·nosql·neo4j
自由的好好干活1 小时前
C#桌面框架与Qt对比及选型(国产操作系统开发视角)
开发语言·qt·c#