qt+vtk 滑条更改点云大小,按钮切换六种视图

目录

通过滑条设置点云大小

添加滑条

添加实现代码

闪退及解决方法

 按钮实现六个视图的切换

给按钮添加图标

按钮切换视图代码


通过滑条设置点云大小

添加滑条

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);
}

代码很简陋,贴出来图一乐,有想法的小伙伴可以精简一波。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值