网格主要用于计算机图形学中,有三角、四角网格等很多种。
计算机图形学中的网格处理绝大部分都是基于三角网格的,三角网格在图形学和三维建模中使用的非常广泛,用来模拟复杂物体的表面,如建筑、车辆、动物等,你看下图中的兔子、球等模型都是基于三角网格的
三角形表示网格也叫三角剖分。它有如下几个优点:
三角网格稳定性强。
三角网格比较简单(主要原因),实际上三角网格是最简单的网格类型之一,可以非常方便并且快速生成,在非结构化网格中最常见。而且相对于一般多边形网格,许多操作对三角网格更容易。
目前点云进行网格生成一般分为两大类方法:
插值法。顾名思义,也就是重建的曲面都是通过原始的数据点得到的
逼近法。用分片线性曲面或其他曲面来逼近原始数据点,得到的重建曲面是原始点集的一个逼近。
- #include
-
- #include
- #include
-
- #include
- #include
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
-
- #include
- #include
- #include
- #include
- #include
-
- #include
- #include
-
- #include
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #include
- #include
- #include
-
-
- #include
- #include
-
- #include
- using namespace std;
-
- //#define FILE_PATH "xiaomianpian.XYZN"
- //#define FILE_PATH "2DpointDatas.txt"
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- using namespace std;
-
- #define FILE_PATH "sxiaomianpian.XYZN"
-
- /
-
- ---------------读取txt文件-------------------
- void CreateCloudFromTxt(const std::string& file_path, pcl::PointCloud
::Ptr cloud, pcl::PointCloud::Ptr normals) - {
- std::ifstream file(file_path.c_str());//c_str():生成一个const char*指针,指向以空字符终止的数组。
- std::string line;
- pcl::PointXYZ point;
- pcl::Normal nPoint;
-
- int index = 0;
- while (getline(file, line)) {
- std::stringstream ss(line);
- ss >> point.x;
- ss >> point.y;
- ss >> point.z;
-
- ss >> nPoint.normal_x;
- ss >> nPoint.normal_y;
- ss >> nPoint.normal_z;
-
- cloud->push_back(point);
- normals->push_back(nPoint);
- //printf("%f,%f,%f\n", point.x, point.y, point.z);
-
- }
- file.close();
- printf("size %ld\n", cloud->size());
- }
- int main(int argc, char** argv)
- {
- pcl::PointCloud
::Ptr cloud(new pcl::PointCloud); - //pcl::PointCloud
::Ptr cloud(new pcl::PointCloud); - //pcl::io::loadPCDFile(FILE_PATH, *cloud);
- pcl::PointCloud
::Ptr normals(new pcl::PointCloud); //存储估计的法线 - CreateCloudFromTxt(FILE_PATH, cloud, normals);
- //CreateCloudFromTxt(FILE_PATH, cloud);
- // printf("size %d\n", cloud->size());
- //pcl::visualization::PCLVisualizer viewer("viewer");
- //viewer.addPointCloud(cloud);
- //viewer.spin();
-
- // Normal estimation*
- //pcl::NormalEstimation
n; //法线估计对象 - //pcl::PointCloud
::Ptr normals(new pcl::PointCloud); //存储估计的法线 - //pcl::search::KdTree
::Ptr tree(new pcl::search::KdTree); //定义kd树指针 - //tree->setInputCloud(cloud); ///用cloud构建tree对象
- //n.setInputCloud(cloud);
- //n.setSearchMethod(tree);
- //n.setKSearch(20);
- //n.compute(*normals); 估计法线存储到其中
- //* normals should not contain the point normals + surface curvatures
- printf("normals=========\n");
- // Concatenate the XYZ and normal fields*
- pcl::PointCloud
::Ptr cloud_with_normals(new pcl::PointCloud); - pcl::concatenateFields(*cloud, *normals, *cloud_with_normals); //连接字段
- //* cloud_with_normals = cloud + normals
- printf("111normals=========\n");
- //定义搜索树对象
- pcl::search::KdTree
::Ptr tree2(new pcl::search::KdTree); - tree2->setInputCloud(cloud_with_normals); //点云构建搜索树
- printf("22 normals=========\n");
- // Initialize objects
- pcl::GreedyProjectionTriangulation
gp3; //定义三角化对象 - pcl::PolygonMesh triangles; //存储最终三角化的网络模型
-
-
-
- 附加顶点信息
- //std::vector
parts = gp3.getPartIDs(); - //std::vector
states = gp3.getPointStates(); -
- std::cout << "Triangling..." << std::endl;
- gp3.setSearchRadius(10);//设置连接点之间的最大距离(即为三角形最大边长)为0.025
- std::cout << "1" << std::endl;
- gp3.setMu(1);//设置被样本点搜索其邻近点的最远距离为2.5,为了适应点云密度的变化
- std::cout << "2" << std::endl;
- gp3.setMaximumNearestNeighbors(100);//设置样本点可搜索的邻域个数
- std::cout << "3" << std::endl;
- gp3.setMaximumSurfaceAngle(M_PI / 12);//45,180/4,设置某点法线方向偏离样本点法线方向的最大角度为45度
- std::cout << "4" << std::endl;
- gp3.setMinimumAngle(M_PI / 18);//10,180/18,设置三角化后得到三角形内角最小角度为10度
- std::cout << "5" << std::endl;
- gp3.setMaximumAngle(2 * M_PI / 12);//120,2*180/3,设置三角化后得到三角形内角最大角度为120度
- std::cout << "6" << std::endl;
- gp3.setNormalConsistency(true); //设置该参数保证法线朝向一致
- std::cout << "7" << std::endl;
-
- gp3.setInputCloud(cloud_with_normals);
- std::cout << "8" << std::endl;
- gp3.setSearchMethod(tree2);//设置搜索方式tree2
- std::cout << "Triangling..." << std::endl;
- gp3.reconstruct(triangles);//重建提取三角化
- std::cout << "Finshed..." << std::endl;
- pcl::io::saveVTKFile("wenwu_result.vtk", triangles);
- //std::cout << "Done..." << std::endl;
- std::cout << "Saved..." << std::endl;
-
- pcl::io::savePolygonFile("wenwu_result.stl", triangles);
- //std::vector
parts = gp3.getPartIDs();//附加定点信息 - //std::vector
states = gp3.getPointStates(); -
- boost::shared_ptr
viewer(new pcl::visualization::PCLVisualizer("可视化"));//三维可视化窗口 - viewer->setBackgroundColor(0, 0, 0);
- viewer->addPolygonMesh(triangles, "my");
- viewer->addCoordinateSystem(50.0);
- viewer->initCameraParameters();
-
- while (!viewer->wasStopped()) {
- viewer->spinOnce(100);
- boost::this_thread::sleep(boost::posix_time::microseconds(100000));
- }
- std::cout << "Done..." << std::endl;
-
- //pcl::io::saveVTKFile("mianpian.vtk", triangles);
-
- //pcl::io::loadPolygonFile(const std::string &file_name, pcl::PolygonMesh& mesh);
- printf("saveVTKFile=========\n");
- system("pause");
- return 0;
- }
- void saveSTL(vtkPolyData* StlPolyData)
- {
- vtkNew
stlWriter; - stlWriter->SetFileName("./db-out.stl");
- stlWriter->SetInputData((vtkDataObject *)StlPolyData );
- stlWriter->Update();
- stlWriter->Write();
- }
- int main()
- {
-
- //vtkSmartPointer
vertices = vtkSmartPointer::New(); //_存放细胞顶点,用于渲染(显示点云所必须的) - vtkSmartPointer
polyData = vtkSmartPointer::New(); - //vtkSmartPointer
pointMapper = vtkSmartPointer::New(); - //vtkSmartPointer
pointActor = vtkSmartPointer::New(); - //vtkSmartPointer
ren1 = vtkSmartPointer< vtkRenderer>::New(); - //vtkSmartPointer
renWin = vtkSmartPointer::New(); - //vtkSmartPointer
iren = vtkSmartPointer::New(); - //vtkSmartPointer
istyle = vtkSmartPointer::New(); -
- vtkSmartPointer
m_Points = vtkSmartPointer::New(); -
- //_读进点云数据信息
-
- ifstream infile(FILE_PATH, ios::in);
- double x, y, z;
- char line[128];
- int i = 0;
- while (infile.getline(line, sizeof(line)))
- {
- stringstream ss(line);
- ss >> x;
- ss >> y;
- ss >> z;
-
- m_Points->InsertPoint(i, x, y, z); //_加入点信息
- ///vertices->InsertNextCell(1); //_加入细胞顶点信息----用于渲染点集
- //vertices->InsertCellPoint(i);
- i++;
- }
- infile.close();
-
- //_创建待显示数据源
-
- polyData->SetPoints(m_Points); //_设置点集
-
- // Triangulate the grid points
- vtkSmartPointer
delaunay = - vtkSmartPointer
::New(); - delaunay->SetInputData(polyData);
- delaunay->SetAlpha(10);
- //delaunay->SetTolerance(0.1);
- delaunay->Update();
-
- saveSTL(delaunay->GetOutput());
- // Visualize
- vtkSmartPointer
colors = - vtkSmartPointer
::New(); -
- vtkSmartPointer
meshMapper = - vtkSmartPointer
::New(); - meshMapper->SetInputConnection(delaunay->GetOutputPort());
-
- vtkSmartPointer
meshActor = - vtkSmartPointer
::New(); - meshActor->SetMapper(meshMapper);
- //meshActor->GetProperty()->SetColor(colors->GetColor3d("Banana").GetData());
- meshActor->GetProperty()->EdgeVisibilityOn();
-
- vtkSmartPointer
glyphFilter = - vtkSmartPointer
::New(); - glyphFilter->SetInputData(polyData);
-
- vtkSmartPointer
pointMapper = - vtkSmartPointer
::New(); - pointMapper->SetInputConnection(glyphFilter->GetOutputPort());
-
- vtkSmartPointer
pointActor = - vtkSmartPointer
::New(); - //pointActor->GetProperty()->SetColor(colors->GetColor3d("Tomato").GetData());
- pointActor->GetProperty()->SetPointSize(5);
- pointActor->SetMapper(pointMapper);
-
- vtkSmartPointer
renderer = - vtkSmartPointer
::New(); - vtkSmartPointer
renderWindow = - vtkSmartPointer
::New(); - renderWindow->AddRenderer(renderer);
- vtkSmartPointer
renderWindowInteractor = - vtkSmartPointer
::New(); - renderWindowInteractor->SetRenderWindow(renderWindow);
-
- renderer->AddActor(meshActor);
- renderer->AddActor(pointActor);
- //renderer->SetBackground(colors->GetColor3d("Mint").GetData());
-
- renderWindow->Render();
- renderWindowInteractor->Start();
- }