以下是一个简单的C++示例,它封装了VTK库以在Qt widget中显示点云。代码注释详细解释了每个步骤和函数的作用。需要注意的是,此示例仅涵盖了基本功能,您可以根据您的需求进行修改和扩展。
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkPLYReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkPointPicker.h>
#include <vtkObjectFactory.h>
#include <QVTKOpenGLWidget.h>
#include <QWidget>
class PointCloudViewer : public QVTKOpenGLWidget
{
Q_OBJECT
public:
explicit PointCloudViewer(QWidget *parent = nullptr)
: QVTKOpenGLWidget(parent)
{
//创建VTK渲染器和窗口
renderer_ = vtkSmartPointer<vtkRenderer>::New();
this->GetRenderWindow()->AddRenderer(renderer_);
this->GetRenderWindow()->SetSize(800, 600);
//设置交互器和交互风格
interactor_style_ = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
interactor_ = this->GetRenderWindow()->GetInteractor();
interactor_->SetInteractorStyle(interactor_style_);
//设置点云选择器
point_picker_ = vtkSmartPointer<vtkPointPicker>::New();
point_picker_->PickFromListOn();
//设置VTK对象
point_cloud_ = vtkSmartPointer<vtkPolyData>::New();
point_cloud_mapper_ = vtkSmartPointer<vtkPolyDataMapper>::New();
point_cloud_actor_ = vtkSmartPointer<vtkActor>::New();
//将点云映射到渲染器中
point_cloud_mapper_->SetInputData(point_cloud_);
point_cloud_actor_->SetMapper(point_cloud_mapper_);
renderer_->AddActor(point_cloud_actor_);
//设置点选中事件回调函数
point_picker_->AddObserver(vtkCommand::EndPickEvent, this, &PointCloudViewer::OnPointPicked);
}
//加载点云
void LoadPointCloud(const std::string& file_name)
{
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
reader->SetFileName(file_name.c_str());
reader->Update();
point_cloud_ = reader->GetOutput();
point_cloud_mapper_->SetInputData(point_cloud_);
this->Render();
}
//显示点云
void ShowPointCloud()
{
point_cloud_actor_->VisibilityOn();
this->Render();
}
//隐藏点云
void HidePointCloud()
{
point_cloud_actor_->VisibilityOff();
this->Render();
}
//删除点云
void RemovePointCloud()
{
renderer_->RemoveActor(point_cloud_actor_);
point_cloud_ = nullptr;
point_cloud_mapper_ = nullptr;
point_cloud_actor_ = nullptr;
this->Render();
}
//渲染函数
void Render()
{
this->GetRenderWindow()->Render();
}
signals:
//选择点的信号
void PointPicked(double x, double y, double z);
protected:
//鼠标单击事件处理程序
virtual void mousePressEvent(QMouseEvent* event) override
{
int* click_pos = this->GetInteractor()->GetEventPosition();
point_picker_->Pick(click_pos[0], click_pos[1], 0, this->renderer_);
}
protected slots:
//点选中事件处理程序
void OnPointPicked()
{
double pick_pos[3];
point_picker_->GetPickPosition(pick_pos);
emit PointPicked(pick_pos[0], pick_pos[1], pick_pos[2]);
}
private:
//VTK对象
vtkSmartPointer<vtkRenderer> renderer_;
vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
vtkSmartPointer<vtkInteractorStyleTrackballCamera> interactor_style_;
vtkSmartPointer<vtkPointPicker> point_picker_;
vtkSmartPointer<vtkPolyData> point_cloud_;
vtkSmartPointer<vtkPolyDataMapper> point_cloud_mapper_;
vtkSmartPointer<vtkActor> point_cloud_actor_;
};
版本2
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkSmartPointer.h>
#include <vtkPLYReader.h>
#include <vtkPointPicker.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkLookupTable.h>
class PointCloudViewer
{
public:
explicit PointCloudViewer(QWidget* parent = nullptr)
{
// 初始化渲染器和渲染窗口
renderer_ = vtkSmartPointer<vtkRenderer>::New();
renderWindow_ = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow_->AddRenderer(renderer_);
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor_->SetRenderWindow(renderWindow_);
// 创建点拾取器
pointPicker_ = vtkSmartPointer<vtkPointPicker>::New();
pointPicker_->SetTolerance(0.01);
// 初始化变量
pointCloud_ = nullptr;
pointCloudMapper_ = nullptr;
pointCloudActor_ = nullptr;
lut_ = vtkSmartPointer<vtkLookupTable>::New();
pointCloudColorMode_ = PointCloudColorMode::Default;
// 设置默认参数
setPointCloudColorMode(PointCloudColorMode::Default);
// 添加交互事件
interactor_->AddObserver(vtkCommand::MouseMoveEvent, this, &PointCloudViewer::OnMouseMove);
interactor_->AddObserver(vtkCommand::LeftButtonPressEvent, this, &PointCloudViewer::OnLeftButtonDown);
}
// 枚举类型,定义点云颜色模式
enum class PointCloudColorMode
{
Default, // 默认颜色
Random, // 随机颜色
Scalar // 根据点云数据的标量值进行颜色映射
};
// 设置点云颜色模式
void setPointCloudColorMode(PointCloudColorMode mode)
{
pointCloudColorMode_ = mode;
switch (pointCloudColorMode_)
{
case PointCloudColorMode::Default:
// 设置默认颜色
lut_->SetNumberOfTableValues(2);
lut_->SetRange(0, 1);
lut_->SetTableValue(0, 1, 1, 1, 1);
lut_->SetTableValue(1, 0, 0, 0, 1);
break;
case PointCloudColorMode::Random:
// 设置随机颜色
lut_->SetNumberOfTableValues(256);
lut_->Build();
lut_->SetTableValue(0, 1, 1, 1, 1);
for (int i = 1; i < 256; i++)
{
double r = static_cast<double>(rand()) / RAND_MAX;
double g = static_cast<double>(rand()) / RAND_MAX;
double b = static_cast<double>(rand()) / RAND_MAX;
lut_->SetTableValue(i, r, g, b, 1);
}
break;
case PointCloudColorMode::
安装检索ID的方式显示隐藏删除点云
void removePointCloud(int id)
{
// 遍历容器,找到需要删除的点云数据结构体,并删除
for (auto iter = pointClouds_.begin(); iter != pointClouds_.end(); iter++)
{
if ((*iter)->id == id)
{
renderer_->RemoveActor((*iter)->actor);
pointClouds_.erase(iter);
break;
}
}
}
void hidePointCloud(int id)
{
// 遍历容器,找到需要隐藏的点云数据结构体,并将其角色从渲染器中移除
for (auto iter = pointClouds_.begin(); iter != pointClouds_.end(); iter++)
{
if ((*iter)->id == id)
{
if ((*iter)->isVisible)
{
(*iter)->isVisible = false;
renderer_->RemoveActor((*iter)->actor);
renderWindow_->Render();
}
break;
}
}
}
void showPointCloud(int id)
{
// 遍历容器,找到需要显示的点云数据结构体,并将其角色添加到渲染器中
for (auto iter = pointClouds_.begin(); iter != pointClouds_.end(); iter++)
{
if ((*iter)->id == id)
{
if (!(*iter)->isVisible)
{
(*iter)->isVisible = true;
renderer_->AddActor((*iter)->actor);
renderWindow_->Render();
}
break;
}
}
}