1. Load point cloud
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); //Create point cloud pointer 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); //mapping vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(polyData); //actor 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();
Load the rgba information in the point cloud file and display it
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); //mapping vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(polyData); //actor vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); actor->GetProperty()->SetPointSize(2); renderer->AddActor(actor); renderer->ResetCamera();
2. Load obj file model
//Read OBJ file 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(); // Create mappers and actors vtkSmartPointer<vtkPolyDataMapper> mapperOBJ = vtkSmartPointer<vtkPolyDataMapper>::New(); mapperOBJ->SetInputConnection(OBJReader->GetOutputPort()); vtkSmartPointer<vtkActor> actorOBJ = vtkSmartPointer<vtkActor>::New(); actorOBJ->SetMapper(mapperOBJ); //Add actor to renderer renderer->AddActor(actorOBJ); renderer->ResetCamera();
3. Load stl file model
//Read STL file 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(); // Create mappers and actors vtkSmartPointer<vtkPolyDataMapper> mapperSTL = vtkSmartPointer<vtkPolyDataMapper>::New(); mapperSTL->SetInputConnection(STLReader->GetOutputPort()); vtkSmartPointer<vtkActor> actorSTL = vtkSmartPointer<vtkActor>::New(); actorSTL->SetMapper(mapperSTL); //Add actor to renderer renderer->AddActor(actorSTL); renderer->ResetCamera();
4. All code
.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" // How to initialize vtk VTK_MODULE_INIT(vtkRenderingOpenGL2); // Rendering VTK_MODULE_INIT(vtkInteractionStyle); //Interaction mode 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;//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>); //Create a point cloud pointer 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); //mapping vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::New(); mapper->SetInputData(polyData); //actor 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() { //Read OBJ file 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(); // Create mappers and actors vtkSmartPointer<vtkPolyDataMapper> mapperOBJ = vtkSmartPointer<vtkPolyDataMapper>::New(); mapperOBJ->SetInputConnection(OBJReader->GetOutputPort()); vtkSmartPointer<vtkActor> actorOBJ = vtkSmartPointer<vtkActor>::New(); actorOBJ->SetMapper(mapperOBJ); //Add actor to renderer renderer->AddActor(actorOBJ); renderer->ResetCamera(); } void Widget::on_load_stl_clicked() { //Read STL file 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(); // Create mappers and actors vtkSmartPointer<vtkPolyDataMapper> mapperSTL = vtkSmartPointer<vtkPolyDataMapper>::New(); mapperSTL->SetInputConnection(STLReader->GetOutputPort()); vtkSmartPointer<vtkActor> actorSTL = vtkSmartPointer<vtkActor>::New(); actorSTL->SetMapper(mapperSTL); //Add actor to renderer renderer->AddActor(actorSTL); renderer->ResetCamera(); }
Show results
5. 3D model download URL
Pro 3D Model :: TurboSquid
6. Question
There is a problem: the point cloud and model are displayed in the slot function. After loading, you need to click on the interface to display them. If they are all written in the constructor, they can be displayed directly. I tried all the update functions I could add, but they didn’t work. What I think is that if we know the source code and what function is executed when the interface is clicked, we can solve the problem. If anyone knows, please leave a message and let me know, thank you very much! ! !
Solved! ! ! ! ! !
Just add the following sentence at the end! ! ! !
ui->vtk_widget->GetRenderWindow()->Render();
For example:
//Read OBJ file 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(); // Create mappers and actors vtkSmartPointer<vtkPolyDataMapper> mapperOBJ = vtkSmartPointer<vtkPolyDataMapper>::New(); mapperOBJ->SetInputConnection(OBJReader->GetOutputPort()); vtkSmartPointer<vtkActor> actorOBJ = vtkSmartPointer<vtkActor>::New(); actorOBJ->SetMapper(mapperOBJ); //Add actor to renderer renderer->AddActor(actorOBJ); renderer->ResetCamera(); ui->vtk_widget->GetRenderWindow()->Render();