VTK —— 二、教程七 - 对点云进行操作(按下r键切换选取或观察模式)(附完整源码)

代码效果

本代码编译运行均在如下链接文章生成的库执行成功,若无VTK库则请先参考如下链接编译vtk源码:

VTK ------ 一、Windows10下编译VTK源码,并用Vs2017代码测试(附编译流程、附编译好的库、vtk测试源码)

教程描述

本示例演示介绍点云操作。按下"r"键可以来回切换对点云的选取或对点云的视图观察操作;按下"f"键对视图进行放大。

完整源码
cpp 复制代码
#include <vtkActor.h>
#include <vtkAreaPicker.h>
#include <vtkDataSetMapper.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkExtractGeometry.h>
#include <vtkIdFilter.h>
#include <vtkIdTypeArray.h>
#include <vtkInteractorStyleRubberBandPick.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkObjectFactory.h>
#include <vtkPlanes.h>
#include <vtkPointData.h>
#include <vtkPointSource.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkSmartPointer.h>
#include <vtkUnstructuredGrid.h>
#include <vtkVersion.h>
#include <vtkVertexGlyphFilter.h>
#include<vtkPropPicker.h>
#if VTK_VERSION_NUMBER >= 89000000000ULL
#define VTK890 1
#endif

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);

namespace {
	// vtkInteractorStyleRubberBandPick: 与TrackBallCamera类似,但它可以在橡皮筋选择矩形下方拾取道具
	class InteractorStyle : public vtkInteractorStyleRubberBandPick
	{
	public:
		static InteractorStyle* New();
		vtkTypeMacro(InteractorStyle, vtkInteractorStyleRubberBandPick);

		InteractorStyle()
		{
			this->SelectedMapper = vtkSmartPointer<vtkDataSetMapper>::New();
			this->SelectedActor = vtkSmartPointer<vtkActor>::New();
			this->SelectedActor->SetMapper(SelectedMapper);
		}

		// 事件绑定
		virtual void OnLeftButtonUp() override
		{
			// 包含颜色及其名称的类
			vtkNew<vtkNamedColors> colors;

			// 转发事件
			vtkInteractorStyleRubberBandPick::OnLeftButtonUp();

			//获取鼠标框选矩形 frustum  
			vtkPlanes* frustum = static_cast<vtkAreaPicker*>(this->GetInteractor()->GetPicker())->GetFrustum();

			// 提取完全位于指定隐式函数内部或外部的单元格
			vtkNew<vtkExtractGeometry> extractGeometry;
			extractGeometry->SetImplicitFunction(frustum);		// 指定内部/外部检查的隐式函数。
			extractGeometry->SetInputData(this->Points);		// 将数据对象指定为输入
			extractGeometry->Update();							// 使此算法的输出保持最新状态

			// 创建一个vtkPolyData,每个点上都有一个顶点
			vtkNew<vtkVertexGlyphFilter> glyphFilter;
			glyphFilter->SetInputConnection(extractGeometry->GetOutputPort()); // 设置给定输入端口索引的连接
			glyphFilter->Update();								// 使此算法的输出保持最新状态

			// 获取此算法上端口的输出数据对象
			vtkPolyData* selected = glyphFilter->GetOutput();
			std::cout << "\nSelected " << selected->GetNumberOfPoints() << " points." << std::endl;
			std::cout << "Selected " << selected->GetNumberOfCells() << " cells." << std::endl;

			vtkIdTypeArray* ids = dynamic_cast<vtkIdTypeArray*>(selected->GetPointData()->GetArray("OriginalIds"));
			for (vtkIdType i = 0; i < ids->GetNumberOfTuples(); i++)
			{
				std::cout << "Id " << i << " : " << ids->GetValue(i) << std::endl;
			}

			this->SelectedMapper->SetInputData(selected);	// 设置此映射器的输入
			this->SelectedMapper->ScalarVisibilityOff();	// 关闭标志以控制是否使用标量数据为对象着色

			this->SelectedActor->GetProperty()->SetColor(colors->GetColor3d("Red").GetData());	// 设置颜色
			this->SelectedActor->GetProperty()->SetPointSize(5);	// 设置点的直径

			this->CurrentRenderer->AddActor(SelectedActor);		// 在渲染器中添加实体
			this->GetInteractor()->GetRenderWindow()->Render();	// 要求此RenderWindow拥有的每个渲染器渲染其图像并同步此过程
			this->HighlightProp(NULL);							// 当挑选成功选择演员时,此方法会适当地突出显示选择的道具
		}


		void SetPoints(vtkSmartPointer<vtkPolyData> points)
		{
			this->Points = points;
		}


	private:
		/*
			是一个数据对象,表示由顶点、直线、多边形和/或三角形条组成的几何结构。点和像元属性值(例如标量、向量等)也被表示。
			具体数据集表示顶点、直线、多边形和三角形条带
		*/
		vtkSmartPointer<vtkPolyData> Points;

		vtkSmartPointer<vtkActor> SelectedActor;			// 创建渲染场景中的实体(几何体和属性)

		vtkSmartPointer<vtkDataSetMapper> SelectedMapper;	// 将vtkDataSet和派生类映射到图形基元
	};


	vtkStandardNewMacro(InteractorStyle);
} // namespace

int main(int, char*[])
{
	// 创建VTK命名颜色
	vtkNew<vtkNamedColors> colors;

	// 创建随机点云,用于在指定中心点的指定半径内创建用户指定的点数
	vtkNew<vtkPointSource> pointSource;
	pointSource->SetNumberOfPoints(20);		// 设置要生成的点数
	pointSource->Update();					// 使此算法的输出保持最新状态

	// 从点和像元ID生成标量或字段数据。是一个过滤器,它使用单元格和点ID生成标量或字段数据
	vtkNew<vtkIdFilter> idFilter;
	idFilter->SetInputConnection(pointSource->GetOutputPort());		// 设置给定输入端口索引的连接
#if VTK890
	idFilter->SetCellIdsArrayName("OriginalIds");
	idFilter->SetPointIdsArrayName("OriginalIds");
#else
	idFilter->SetIdsArrayName("OriginalIds");						// 如果已生成,则设置Ids数组的名称
#endif
	idFilter->Update();												// 使此算法的输出保持最新状态

	// 提取任何数据集的外表面。是一个通用过滤器,用于从任何类型的数据集中提取边界几何图形(和关联数据)
	vtkNew<vtkDataSetSurfaceFilter> surfaceFilter;
	surfaceFilter->SetInputConnection(idFilter->GetOutputPort());	// 设置给定输入端口索引的连接
	surfaceFilter->Update();										// 使此算法的输出保持最新状态

	/* 
		是一个数据对象,表示由顶点、直线、多边形和/或三角形条组成的几何结构。点和像元属性值(例如标量、向量等)也被表示。
		具体数据集表示顶点、直线、多边形和三角形条带

		surfaceFilter->GetOutput(): 获取此算法上端口的输出数据对象
	*/
	vtkPolyData* input = surfaceFilter->GetOutput();

	// 将vtkPolyData映射到图形基元
	vtkNew<vtkPolyDataMapper> mapper;
	mapper->SetInputData(input);			// 指定要映射的输入数据
	mapper->ScalarVisibilityOff();			// 关闭标志以控制是否使用标量数据为对象着色

	// 创建渲染场景中的实体(几何体和属性)
	vtkNew<vtkActor> actor;
	actor->SetMapper(mapper);				// 设置映射器: 将参与者连接到可视化管道末尾
	actor->GetProperty()->SetPointSize(3);	// 设置点的直径
	actor->GetProperty()->SetColor(colors->GetColor3d("Gold").GetData());	// 设置模型颜色

	// 创建渲染
	vtkNew<vtkRenderer> renderer;			// 创建渲染器
	vtkNew<vtkRenderWindow> renderWindow;	// 为渲染器创建绘制窗口
	renderWindow->AddRenderer(renderer);	// 窗口添加渲染器
	renderWindow->SetWindowName("HighlightSelectedPoints");	// 设置渲染窗口名称

	// 创建选取视口上选择矩形后面的道具
	vtkNew<vtkAreaPicker> areaPicker;
	// 与平台无关的渲染窗互,包括拾取和帧速率控制。
	vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
	renderWindowInteractor->SetPicker(areaPicker);			// 设置用于执行拣选操作的对象
	renderWindowInteractor->SetRenderWindow(renderWindow);	// 设置由此对象控制的渲染窗口


	renderer->AddActor(actor);			// 在渲染器中添加实体
	renderer->SetBackground(colors->GetColor3d("DarkSlateGray").GetData());	// 设置渲染屏幕背景色

	// 要求此RenderWindow拥有的每个渲染器渲染其图像并同步此过程
	renderWindow->Render();


	vtkNew<InteractorStyle> style;
	style->SetPoints(input);
	//style->StartSelect();//开始选取
	renderWindowInteractor->SetInteractorStyle(style);	// 在操纵杆/轨迹球/新设备之间进行外部切换

	// 启动交互器事件循环
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}

笔者

笔者 - jxd

相关推荐
zz40_2 分钟前
C++自己写类 和 运算符重载函数
c++
六月的翅膀14 分钟前
C++:实例访问静态成员函数和类访问静态成员函数有什么区别
开发语言·c++
liujjjiyun44 分钟前
小R的随机播放顺序
数据结构·c++·算法
¥ 多多¥1 小时前
c++中mystring运算符重载
开发语言·c++·算法
天若有情6732 小时前
c++框架设计展示---提高开发效率!
java·c++·算法
Root_Smile2 小时前
【C++】类和对象
开发语言·c++
Reese_Cool2 小时前
【数据结构与算法】排序
java·c语言·开发语言·数据结构·c++·算法·排序算法
寒笙LED3 小时前
C++详细笔记(六)string库
开发语言·c++·笔记
就爱六点起5 小时前
C/C++ 中的类型转换方式
c语言·开发语言·c++
召木6 小时前
C++小白实习日记——Day 2 TSCNS怎么读取当前时间
c++·职场和发展