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

16 篇文章 5 订阅

一、什么是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<vtkPLYReader> PLYReader = vtkSmartPointer<vtkPLYReader>::New();
    PLYReader->SetFileName(fileName.toStdString().c_str());
    PLYReader->Update();

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

运行结果

三、读取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<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New ();
    //方法1 需加头文件#include <pcl/io/vtk_lib_io.h>
    pcl::io::mesh2vtk(poly_mesh, poly_data);
    //方法2 需加头文件#include <pcl/surface/vtk_smoothing/vtk_utils.h>
    pcl::VTKUtils::convertToVTK (poly_mesh, poly_data);

    //映射
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputData(poly_data);
    //演员
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::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<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New ();
    //方法1 需加头文件#include <pcl/io/vtk_lib_io.h>
    pcl::io::mesh2vtk(poly_mesh, poly_data);
    //方法2 需加头文件#include <pcl/surface/vtk_smoothing/vtk_utils.h>
    pcl::VTKUtils::convertToVTK (poly_mesh, poly_data);

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

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

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

运行结果

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

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

利用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<pcl::PointXYZ> cloud;
    pcl::fromPCLPointCloud2(poly_mesh.cloud,cloud);

    std::vector<Eigen::Vector3d> 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<Eigen::Vector3i> 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> vtkpoints = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> cellArray = vtkSmartPointer<vtkCellArray>::New();
    vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::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<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    polyData->SetPoints(vtkpoints);
    polyData->SetPolys(cellArray);
    polyData->GetCellData()->SetScalars(colors);

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

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

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

运行结果:

资源见https://download.csdn.net/download/m0_67254672/88955839?spm=1001.2014.3001.5501

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值