代码效果
本代码编译运行均在如下链接文章生成的库执行成功,若无VTK库则请先参考如下链接编译vtk源码:
VTK —— 一、Windows10下编译VTK源码,并用Vs2017代码测试(附编译流程、附编译好的库、vtk测试源码)
教程描述
本示例演示介绍点云操作。按下"r"键可以来回切换对点云的选取或对点云的视图观察操作;按下"f"键对视图进行放大。
完整源码
#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);
} // namespaceint 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 VTK890idFilter->SetCellIdsArrayName("OriginalIds");idFilter->SetPointIdsArrayName("OriginalIds");
#elseidFilter->SetIdsArrayName("OriginalIds"); // 如果已生成,则设置Ids数组的名称
#endifidFilter->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