目录
通过滑条设置点云大小
添加滑条
ui界面中添加一个垂直滑条,在input widgets中倒数第四个
添加实现代码
转到mainwindow.cpp的构造函数中,添加如下代码
ui->verticalScrollBar->setMinimum(1);//设置最小值
ui->verticalScrollBar->setMaximum(5);//设置最大值
ui->verticalScrollBar->setSingleStep(1);//设置单击上下箭头时的步长
ui->verticalScrollBar->setPageStep(1);//设置拖动滑块时的步长
ui->verticalScrollBar->setValue(1);//设置一开始滑块所在位置
ui->verticalScrollBar->setToolTip("Point Size");
connect(ui->verticalScrollBar, &QScrollBar::valueChanged, this, [=](int value){
vtkRenderWindow* renderWindow = ui->qvtkWidget->GetRenderWindow();
vtkRenderer* renderer = renderWindow->GetRenderers()->GetFirstRenderer();
vtkActor* actor = renderer->GetActors()->GetLastActor();
actor->GetProperty()->SetPointSize(value);
renderWindow->Render();
});
通过ui->qvtkWidget->GetRenderWindow()获取vtkRenderWindow对象,进而获取renderer和actor。然后通过actor->GetProperty()->SetPointSize(value)设置点云大小。最后调用renderWindow->Render()方法更新渲染窗口。
闪退及解决方法
上面代码如果在没有读取点云的时候拖动滑块会导致闪退。
最简单的解决方法为:
在其之前添加一行代码
ui->verticalScrollBar->setEnabled(false); // 禁用滑块
然后在读取点云的代码最后面添加启用滑块的代码
ui->verticalScrollBar->setEnabled(true);
当然也有其他解决方法,只是提供个方法,没上面简洁,图一乐,可以略过。
比如在mainwindow.h中添加一个bool变量pointCloudLoaded
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
bool pointCloudLoaded; // 添加此行声明 pointCloudLoaded 成员变量
// 其他成员函数和变量声明
};
将connect部分修改为
connect(ui->verticalScrollBar, &QScrollBar::valueChanged, this, [=](int value){
if (pointCloudLoaded) { // 如果点云已加载
vtkRenderWindow* renderWindow = ui->qvtkWidget->GetRenderWindow();
vtkRenderer* renderer = renderWindow->GetRenderers()->GetFirstRenderer();
vtkActor* actor = renderer->GetActors()->GetLastActor();
actor->GetProperty()->SetPointSize(value);
renderWindow->Render();
} else { // 如果点云尚未加载
ui->verticalScrollBar->setValue(1); // 将滑块重置为最小值
ui->verticalScrollBar->setEnabled(false); // 禁用滑块
}
然后跟上面禁用滑块一样,在 ui->setupUi(this);下面添加一行代码,如下
ui->setupUi(this);
pointCloudLoaded = false;
这样如果没读取点云就点击滑块的话就将滑块禁用了(那我不如直接一开始就给它禁了。。。)
在读取点云的代码的最后可以添加
pointCloudLoaded = true;
// 启用滑块
ui->verticalScrollBar->setEnabled(true);
按钮实现六个视图的切换
给按钮添加图标
这里有六个视图的不同图标,可以下载下来
https://wwpb.lanzoue.com/ixCbM0tct1qd 密码:cj9h
首先,在ui界面添加6个pushbutton,按照自己喜欢的方式排列
然后 ,在qt中右键自己的项目名,add new,先创建一个资源文件:qt -> qt resource file
修改名称,在cmakelists.txt中添加刚新建的.qrc名称,叉掉,save all
左侧选中.qrc资源文件,右键,open in editor,弹出的界面首先点击add prefix添加前缀,然后add files添加需要的图标等资源文件。右键单击要使用的文件,复制地址到粘贴板。
在mainwindow.cpp的构造函数中,添加更改图标的代码
ui->pushButton_5->setIcon(QIcon(":/new/prefix1/俯.png"));
ui->pushButton_6->setIcon(QIcon(":/new/prefix1/前.png"));
ui->pushButton_7->setIcon(QIcon(":/new/prefix1/左.png"));
ui->pushButton_8->setIcon(QIcon(":/new/prefix1/后.png"));
ui->pushButton_9->setIcon(QIcon(":/new/prefix1/右.png"));
ui->pushButton_10->setIcon(QIcon(":/new/prefix1/上.png"));
如果图标显示太小,可以在为每一个图标设置为自适应按钮的大小
在后面添加下面的代码,有几个按钮添加几个,如果按钮一样大只需要修改前面的pushButton即可
ui->pushButton_5->setIconSize(ui->pushButton_5->size());
按钮切换视图代码
在mainwindow.h中添加vtk相关头文件
#include <vtkCamera.h>
#include <vtkBoundingBox.h>
#include <vtkRendererCollection.h>
#include <vtkMath.h>
private:下声明函数
void updateCameraView(double focalPoint[3], double position[3], double viewUp[3]);
mainwindow.cpp添加相关函数
void MainWindow::updateCameraView(double focalPoint[3], double position[3], double viewUp[3])
{
vtkCamera* camera = ui->qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
camera->SetFocalPoint(focalPoint);
camera->SetPosition(position);
camera->SetViewUp(viewUp);
// 刷新渲染窗口
ui->qvtkWidget->GetRenderWindow()->Render();
}
给代表每个视图的按钮编写槽函数,实现以点云中心为相机中心,切换视图后能够完整显示整个点云。
void MainWindow::on_pushButton_5_clicked()//俯视图
{
vtkPolyData* polydata = vtkPolyData::SafeDownCast(ui->qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActors()->GetLastActor()->GetMapper()->GetInput());
double center[3];
polydata->GetCenter(center);
double bounds[6];
polydata->GetBounds(bounds);
double max_range = std::max({bounds[1]-bounds[0], bounds[3]-bounds[2], bounds[5]-bounds[4]});
double cam_distance = max_range / tan(45.0*vtkMath::Pi()/360.0);
double cam_height = cam_distance * tan(vtkMath::Pi()/4.0);
double position[3] = {center[0], center[1], center[2]+cam_height};
double viewUp[3] = {0.0, 1.0, 0.0};
updateCameraView(center, position, viewUp);
}
void MainWindow::on_pushButton_6_clicked()//前视图
{
vtkPolyData* polydata = vtkPolyData::SafeDownCast(ui->qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActors()->GetLastActor()->GetMapper()->GetInput());
double center[3];
polydata->GetCenter(center);
double bounds[6];
polydata->GetBounds(bounds);
double max_range = std::max({bounds[1]-bounds[0], bounds[3]-bounds[2], bounds[4]});
double cam_distance = max_range / tan(45.0*vtkMath::Pi()/360.0);
double position[3] = {center[0], center[1]-cam_distance, center[2]};
double viewUp[3] = {0.0, 0.0, 1.0};
updateCameraView(center, position, viewUp);
}
void MainWindow::on_pushButton_7_clicked()//左视图
{
vtkPolyData* polydata = vtkPolyData::SafeDownCast(ui->qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActors()->GetLastActor()->GetMapper()->GetInput());
double center[3];
polydata->GetCenter(center);
double bounds[6];
polydata->GetBounds(bounds);
double max_range = std::max({bounds[0], bounds[3]-bounds[2], bounds[5]-bounds[4]});
double cam_distance = max_range / tan(45.0*vtkMath::Pi()/360.0);
double position[3] = {center[0]-cam_distance, center[1], center[2]};
double viewUp[3] = {0.0, 0.0, 1.0};
updateCameraView(center, position, viewUp);
}
void MainWindow::on_pushButton_8_clicked()//后视图
{
vtkPolyData* polydata = vtkPolyData::SafeDownCast(ui->qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActors()->GetLastActor()->GetMapper()->GetInput());
double center[3];
polydata->GetCenter(center);
double bounds[6];
polydata->GetBounds(bounds);
double max_range = std::max({bounds[0]-bounds[1], bounds[3]-bounds[2], bounds[5]-bounds[4]});
double cam_distance = max_range / tan(45.0*vtkMath::Pi()/360.0);
double position[3] = {center[0], center[1]+cam_distance, center[2]};
double viewUp[3] = {0.0, 0.0, 1.0};
updateCameraView(center, position, viewUp);
}
void MainWindow::on_pushButton_9_clicked()//右视图
{
vtkPolyData* polydata = vtkPolyData::SafeDownCast(ui->qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActors()->GetLastActor()->GetMapper()->GetInput());
double center[3];
polydata->GetCenter(center);
double bounds[6];
polydata->GetBounds(bounds);
double max_range = std::max({bounds[1], bounds[3]-bounds[2], bounds[5]-bounds[4]});
double cam_distance = max_range / tan(45.0*vtkMath::Pi()/360.0);
double position[3] = {center[0]+cam_distance, center[1], center[2]};
double viewUp[3] = {0.0, 0.0, 1.0};
updateCameraView(center, position, viewUp);
}
void MainWindow::on_pushButton_10_clicked()//仰视图
{
vtkPolyData* polydata = vtkPolyData::SafeDownCast(ui->qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActors()->GetLastActor()->GetMapper()->GetInput());
double center[3];
polydata->GetCenter(center);
double bounds[6];
polydata->GetBounds(bounds);
double max_range = std::max({bounds[1]-bounds[0], bounds[5]-bounds[4], bounds[2]-bounds[3]});
double cam_distance = max_range / tan(45.0*vtkMath::Pi()/360.0);
double cam_height = cam_distance * tan(vtkMath::Pi()/4.0);
double position[3] = {center[0], center[1], center[2]-cam_height};
double viewUp[3] = {0.0, -1.0, 0.0};
updateCameraView(center, position, viewUp);
}
代码很简陋,贴出来图一乐,有想法的小伙伴可以精简一波。