Mesh模型是一种用于描述三维物体表面的数学表示方法。它由一系列顶点(vertices)和连接这些顶点的线段或面片(faces)组成。每个顶点具有其在三维空间中的坐标位置,而每个面片则由一组顶点索引构成,定义了一个平面。在Mesh模型中,可以使用不同的数据结构来表示顶点和面片之间的关系,常见的包括三角形网格(triangle mesh)和四边形网格(quadrilateral mesh)三角形网格是最常用的一种,它由三个顶点和一个法线向量(用于确定面片的朝向)组成。四边形网格则由四个顶点和一个法线向量构成。
除了顶点和面片信息,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::PolygonMesh时,显示mesh模型。
下面例子模拟了将.ply文件中的数据以pcl::PolygonMesh的数据格式加载出来,pcl中提供了直接将pcl::PolygonMesh数据格式转化为vtk中显示mesh模型所需要的vtkPolyData数据集。
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();
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();
运行结果
下面例子模拟了将.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();
运行结果: