pcl+vtk(九)QVTKOpenGLNativeWidget同时显示点云和模型

一、加载点云

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);   //创建点云指针
    QString fileName = QFileDialog::getOpenFileName(this, "Open PointCloud", ".", "Open PCD files(*.pcd)");
    if(fileName == "") return;
    pcl::io::loadPCDFile(fileName.toStdString(),*cloud);
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> vertices  = vtkSmartPointer<vtkCellArray>::New();

    for (int i = 0; i<cloud->size(); i++)
    {
        vtkIdType pid[1];
        pid[0] =  points->InsertNextPoint(cloud->at(i).x, cloud->at(i).y, cloud->at(i).z);
        vertices->InsertNextCell(1, pid);
    }

    vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    polyData->SetPoints(points);
    polyData->SetVerts(vertices);

    //映射
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputData(polyData);
    //演员
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
    actor->GetProperty()->SetPointSize(2);
    renderer->AddActor(actor);

    renderer->ResetCamera();

 加载点云文件中的rgba信息并显示

    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>);
    QString fileName = QFileDialog::getOpenFileName(this, "Open PointCloud", ".", "Open PCD files(*.pcd)");
    if(fileName == "") return;
    pcl::io::loadPCDFile(fileName.toStdString(),*cloud);
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> vertices  = vtkSmartPointer<vtkCellArray>::New();
    vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
    colors->SetNumberOfComponents(4);
    for (int i = 0; i<cloud->size(); i++)
    {
        vtkIdType pid[1];
        pid[0] =  points->InsertNextPoint(cloud->at(i).x, cloud->at(i).y, cloud->at(i).z);
        vertices->InsertNextCell(1, pid);
        unsigned char col[4] = {cloud->at(i).r,cloud->at(i).g,cloud->at(i).b,cloud->at(i).a};
        colors->InsertNextTypedTuple(col);
    }
    vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    polyData->SetPoints(points);
    polyData->SetVerts(vertices);
    polyData->GetPointData()->SetScalars(colors);

    //映射
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputData(polyData);
    //演员
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
    actor->GetProperty()->SetPointSize(2);
    renderer->AddActor(actor);

    renderer->ResetCamera();

二、加载obj文件模型

    //读取 OBJ 文件
    vtkSmartPointer<vtkOBJReader> OBJReader = vtkSmartPointer<vtkOBJReader>::New();
    QString fileName = QFileDialog::getOpenFileName(this, "Open OBJ", ".", "Open PCD files(*.obj)");
    if(fileName == "") return;
    OBJReader->SetFileName(fileName.toStdString().c_str());
    OBJReader->Update();
    // 创建映射器和演员
    vtkSmartPointer<vtkPolyDataMapper> mapperOBJ = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapperOBJ->SetInputConnection(OBJReader->GetOutputPort());
    vtkSmartPointer<vtkActor> actorOBJ = vtkSmartPointer<vtkActor>::New();
    actorOBJ->SetMapper(mapperOBJ);
    // 添加演员到渲染器
    renderer->AddActor(actorOBJ);
    renderer->ResetCamera();

三、加载stl文件模型

    //读取 STL 文件
    vtkSmartPointer<vtkSTLReader> STLReader = vtkSmartPointer<vtkSTLReader>::New();
    QString fileName = QFileDialog::getOpenFileName(this, "Open STL", ".", "Open PCD files(*.stl)");
    if(fileName == "") return;
    STLReader->SetFileName(fileName.toStdString().c_str());
    STLReader->Update();
    // 创建映射器和演员
    vtkSmartPointer<vtkPolyDataMapper> mapperSTL = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapperSTL->SetInputConnection(STLReader->GetOutputPort());
    vtkSmartPointer<vtkActor> actorSTL = vtkSmartPointer<vtkActor>::New();
    actorSTL->SetMapper(mapperSTL);
    // 添加演员到渲染器
    renderer->AddActor(actorSTL);
    renderer->ResetCamera();

四、全部代码

.pro

#-------------------------------------------------
#
# Project created by QtCreator 2023-10-23T11:32:27
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = vtk_pointCloud_obj
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp \
        widget.cpp

HEADERS += \
        widget.h

FORMS += \
        widget.ui

INCLUDEPATH += /usr/include/eigen3

INCLUDEPATH += /usr/local/include/vtk-8.2
LIBS += /usr/local/lib/libvtk*.so

INCLUDEPATH += /usr/local/include/pcl-1.13
LIBS += /usr/local/lib/libpcl_*.so

main..cpp

#include "widget.h"
#include <QApplication>
#include <QSurfaceFormat>
#include "QVTKOpenGLNativeWidget.h"

int main(int argc, char *argv[])
{
    QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

.ui

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "vtkAutoInit.h"   // vtk初始化的方式
VTK_MODULE_INIT(vtkRenderingOpenGL2);   // 渲染
VTK_MODULE_INIT(vtkInteractionStyle);   // 相互做用方式
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);  //
VTK_MODULE_INIT(vtkRenderingFreeType);
#include <pcl/io/pcd_io.h>
#include <vtkSmartPointer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkActor.h"
#include "vtkProperty.h"
#include "vtkConeSource.h"
#include <vtkSTLReader.h>
#include <vtkOBJReader.h>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_load_pointCould_clicked();

    void on_load_obj_clicked();

    void on_load_stl_clicked();

private:
    Ui::Widget *ui;

    vtkSmartPointer<vtkRenderer> renderer;//渲染器

};

#endif // WIDGET_H

 widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QFileDialog>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    renderer = vtkSmartPointer<vtkRenderer>::New();

    vtkNew<vtkGenericOpenGLRenderWindow> renwindow;
    renwindow->AddRenderer(renderer);
    ui->vtk_widget->SetRenderWindow(renwindow.Get());
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_load_pointCould_clicked()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);   //创建点云指针
    QString fileName = QFileDialog::getOpenFileName(this, "Open PointCloud", ".", "Open PCD files(*.pcd)");
    if(fileName == "") return;
    pcl::io::loadPCDFile(fileName.toStdString(),*cloud);//"/home/li/pcd/bun_zipper.pcd"
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> vertices  = vtkSmartPointer<vtkCellArray>::New();

    for (int i = 0; i<cloud->size(); i++)
    {
        vtkIdType pid[1];
        pid[0] =  points->InsertNextPoint(cloud->at(i).x, cloud->at(i).y, cloud->at(i).z);
        vertices->InsertNextCell(1, pid);
    }

    vtkSmartPointer<vtkPolyData> polyData = vtkPolyData::New();
    polyData->SetPoints(points);
    polyData->SetVerts(vertices);

    //映射
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::New();
    mapper->SetInputData(polyData);
    //演员
    vtkSmartPointer<vtkActor> actor = vtkActor::New();
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
    actor->GetProperty()->SetPointSize(2);
    renderer->AddActor(actor);

    renderer->ResetCamera();
}

void Widget::on_load_obj_clicked()
{
    //读取 OBJ 文件
    vtkSmartPointer<vtkOBJReader> OBJReader = vtkSmartPointer<vtkOBJReader>::New();
    QString fileName = QFileDialog::getOpenFileName(this, "Open OBJ", ".", "Open PCD files(*.obj)");
    if(fileName == "") return;
    OBJReader->SetFileName(fileName.toStdString().c_str()); //"/home/li/pcd/RedLeaf.obj"
    OBJReader->Update();
    // 创建映射器和演员
    vtkSmartPointer<vtkPolyDataMapper> mapperOBJ = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapperOBJ->SetInputConnection(OBJReader->GetOutputPort());
    vtkSmartPointer<vtkActor> actorOBJ = vtkSmartPointer<vtkActor>::New();
    actorOBJ->SetMapper(mapperOBJ);
    // 添加演员到渲染器
    renderer->AddActor(actorOBJ);
    renderer->ResetCamera();
}

void Widget::on_load_stl_clicked()
{
    //读取 STL 文件
    vtkSmartPointer<vtkSTLReader> STLReader = vtkSmartPointer<vtkSTLReader>::New();
    QString fileName = QFileDialog::getOpenFileName(this, "Open STL", ".", "Open PCD files(*.stl)");
    if(fileName == "") return;
    STLReader->SetFileName(fileName.toStdString().c_str()); //"/home/li/pcd/skull_50.stl"
    STLReader->Update();
    // 创建映射器和演员
    vtkSmartPointer<vtkPolyDataMapper> mapperSTL = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapperSTL->SetInputConnection(STLReader->GetOutputPort());
    vtkSmartPointer<vtkActor> actorSTL = vtkSmartPointer<vtkActor>::New();
    actorSTL->SetMapper(mapperSTL);
    // 添加演员到渲染器
    renderer->AddActor(actorSTL);
    renderer->ResetCamera();
}

 效果展示

五、3d模型下载网址

 专业版 3D 模型 :: TurboSquid

六、问题

有个问题:在槽函数中显示点云和模型,加载出来之后,需要点击一下界面才能显示出来,如果全部写在构造函数中就可以直接全部显示出来。我把能加的update函数都试了一遍,都不管用。想的是如果知道点击界面时的源码,执行了什么函数,就可以解决差问题了。如果有知道的朋友一定要留言告知呀,万分感谢!!!

解决啦!!!!!!

只需要在最后加上下面这句就可以啦!!!!

    ui->vtk_widget->GetRenderWindow()->Render();

例如:

    //读取 OBJ 文件
    vtkSmartPointer<vtkOBJReader> OBJReader = vtkSmartPointer<vtkOBJReader>::New();
    QString fileName = QFileDialog::getOpenFileName(this, "Open OBJ", ".", "Open PCD files(*.obj)");
    if(fileName == "") return;
    OBJReader->SetFileName(fileName.toStdString().c_str()); //"/home/li/pcd/RedLeaf.obj"
    OBJReader->Update();
    // 创建映射器和演员
    vtkSmartPointer<vtkPolyDataMapper> mapperOBJ = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapperOBJ->SetInputConnection(OBJReader->GetOutputPort());
    vtkSmartPointer<vtkActor> actorOBJ = vtkSmartPointer<vtkActor>::New();
    actorOBJ->SetMapper(mapperOBJ);
    // 添加演员到渲染器
    renderer->AddActor(actorOBJ);
    renderer->ResetCamera();
    ui->vtk_widget->GetRenderWindow()->Render();

猜你喜欢

转载自blog.csdn.net/m0_67254672/article/details/134008609
今日推荐