一、加载点云
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 = 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();
二、加载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();
ui->vtk_widget->update();
}
效果展示
五、3d模型下载网址
专业版 3D 模型 :: TurboSquid
有个问题:在槽函数中显示点云和模型,加载出来之后,需要点击一下界面才能显示出来,如果全部写在构造函数中就可以直接全部显示出来。我把能加的update函数都试了一遍,都不管用。想的是如果知道点击界面时的源码,执行了什么函数,就可以解决差问题了。如果有知道的朋友一定要留言告知呀,万分感谢!!!