pcl+vtk(十三)mesh模型的加载显示

一、什么是mesh模型

        Mesh模型是一种用于描述三维物体表面的数学表示方法。它由一系列顶点(vertices)和连接这些顶点的线段或面片(faces)组成。每个顶点具有其在三维空间中的坐标位置,而每个面片则由一组顶点索引构成,定义了一个平面。在Mesh模型中,可以使用不同的数据结构来表示顶点和面片之间的关系,常见的包括三角形网格(triangle mesh)和四边形网格(quadrilateral mesh)三角形网格是最常用的一种,它由三个顶点和一个法线向量(用于确定面片的朝向)组成。四边形网格则由四个顶点和一个法线向量构成。
        除了顶点和面片信息,Mesh模型还可以包含其他属性,如颜色、纹理坐标、法线向量等。这些属性可以为模型添加更多的细节和真实感。

二、加载ply格式显示mesh模型

加载存放mesh结构的.ply文件。

    QString fileName = QFileDialog::getOpenFileName(this, "Open PLY", ".", "Open PCD files(*.ply)");
    if(fileName == "") return;
    vtkSmartPointer PLYReader = vtkSmartPointer::New();
    PLYReader->SetFileName(fileName.toStdString().c_str());
    PLYReader->Update();

    //映射
    vtkSmartPointer mapper = vtkSmartPointer::New();
    mapper->SetInputConnection(PLYReader->GetOutputPort());
    //演员
    vtkSmartPointer actor = vtkSmartPointer::New();
    actor->SetMapper(mapper);
    renderer->AddActor(actor);
    
    renderer->ResetCamera();
    ui->vtk_widget->GetRenderWindow()->Render();

运行结果

pcl+vtk(十三)mesh模型的加载显示_第1张图片

三、读取pcl::PolygonMesh数据格式显示mesh模型

当拿到的数据格式为pcl::PolygonMesh时,显示mesh模型。

下面例子模拟了将.ply文件中的数据以pcl::PolygonMesh的数据格式加载出来,pcl中提供了直接将pcl::PolygonMesh数据格式转化为vtk中显示mesh模型所需要的vtkPolyData数据集。

方法1:

    QString fileName = QFileDialog::getOpenFileName(this, "Open PLY", ".", "Open PCD files(*.ply)");
    if(fileName == "") return;
    // 将ply格式数据加载为PolygonMesh对象
    pcl::PolygonMesh poly_mesh;
    if(pcl::io::loadPLYFile(fileName.toStdString(), poly_mesh) == -1)
    {
        qDebug()<<"load ply file fail.";
        return;
    }
    vtkSmartPointer poly_data = vtkSmartPointer::New ();
    //方法1 需加头文件#include 
    pcl::io::mesh2vtk(poly_mesh, poly_data);
    //方法2 需加头文件#include 
    pcl::VTKUtils::convertToVTK (poly_mesh, poly_data);

    //映射
    vtkSmartPointer mapper = vtkSmartPointer::New();
    mapper->SetInputData(poly_data);
    //演员
    vtkSmartPointer actor = vtkSmartPointer::New();
    actor->SetMapper(mapper);
    renderer->AddActor(actor);

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

方法2:

    QString fileName = QFileDialog::getOpenFileName(this, "Open PLY", ".", "Open PCD files(*.ply)");
    if(fileName == "") return;
    // 将ply格式数据加载为PolygonMesh对象
    pcl::PolygonMesh poly_mesh;
    if(pcl::io::loadPLYFile(fileName.toStdString(), poly_mesh) == -1)
    {
        qDebug()<<"load ply file fail.";
        return;
    }
    vtkSmartPointer poly_data = vtkSmartPointer::New ();
    //方法1 需加头文件#include 
    pcl::io::mesh2vtk(poly_mesh, poly_data);
    //方法2 需加头文件#include 
    pcl::VTKUtils::convertToVTK (poly_mesh, poly_data);

    vtkSmartPointer triangleFilter = vtkSmartPointer::New ();
    triangleFilter->SetInputData (poly_data);

    //映射
    vtkSmartPointer mapper = vtkSmartPointer::New();
    mapper->SetInputConnection (triangleFilter->GetOutputPort ());
    //演员
    vtkSmartPointer actor = vtkSmartPointer::New();
    actor->SetMapper(mapper);
    renderer->AddActor(actor);

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

运行结果

pcl+vtk(十三)mesh模型的加载显示_第2张图片

四、点云Eigen::Vector3d,面片Eigen::Vector3i数据格式显示mesh模型

下面例子模拟了将.ply文件中的数据以pcl::PolygonMesh的数据格式加载出来,并将pcl::PolygonMesh数据结构中的pcl::PCLPointCloud2转为pcl::PointCloud,拿到点云数据以及面片数据。

利用vtkUnsignedCharArray添加mesh模型的颜色,具体使用如下:

    QString fileName = QFileDialog::getOpenFileName(this, "Open PLY", ".", "Open PCD files(*.ply)");
    if(fileName == "") return;
    // 将ply格式数据加载为PolygonMesh对象
    pcl::PolygonMesh poly_mesh;
    if(pcl::io::loadPLYFile(fileName.toStdString(), poly_mesh) == -1)
    {
        qDebug()<<"load ply file fail.";
        return;
    }

    pcl::PointCloud cloud;
    pcl::fromPCLPointCloud2(poly_mesh.cloud,cloud);

    std::vector points;
    for(int i = 0;i < cloud.size();i++)
    {
        Eigen::Vector3d point;
        point[0] = cloud.at(i).x;
        point[1] = cloud.at(i).y;
        point[2] = cloud.at(i).z;
        points.push_back(point);
    }

    std::vector triangles;
    for(int i = 0;i < poly_mesh.polygons.size();i++)
    {
        Eigen::Vector3i triangle;
        triangle[0] = poly_mesh.polygons.at(i).vertices.at(0);
        triangle[1] = poly_mesh.polygons.at(i).vertices.at(1);
        triangle[2] = poly_mesh.polygons.at(i).vertices.at(2);
        triangles.push_back(triangle);
    }

    vtkSmartPointer vtkpoints = vtkSmartPointer::New();
    vtkSmartPointer cellArray = vtkSmartPointer::New();
    vtkSmartPointer colors = vtkSmartPointer::New();
    colors->SetNumberOfComponents(4);
    for(int i = 0;i < points.size();i++)
    {
        vtkpoints->InsertNextPoint(points.at(i)[0],points.at(i)[1],points.at(i)[2]);
    }
    for(int i = 0;i < triangles.size();i++)
    {
        vtkIdType pid[3] = {triangles.at(i)[0],triangles.at(i)[1],triangles.at(i)[2]};
        cellArray->InsertNextCell(3, pid);

        unsigned char col[4] = {0,255,255,255};
        colors->InsertNextTypedTuple(col);
    }

    vtkSmartPointer polyData = vtkSmartPointer::New();
    polyData->SetPoints(vtkpoints);
    polyData->SetPolys(cellArray);
    polyData->GetCellData()->SetScalars(colors);

    vtkSmartPointer mapper = vtkSmartPointer::New();
    mapper->SetInputData(polyData);

    vtkSmartPointer actor = vtkSmartPointer::New();
    actor->SetMapper(mapper);
    renderer->AddActor(actor);

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

运行结果:

pcl+vtk(十三)mesh模型的加载显示_第3张图片

你可能感兴趣的:(pcl+vtk,QT,vtk,qt,前端)