代码效果
本代码编译运行均在如下链接文章生成的库执行成功,若无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