0
点赞
收藏
分享

微信扫一扫

pcl下对多个ply网格文件合并

五殳师兄 2022-03-12 阅读 163

由于自己需要对点云数据进行分段建模,建模之后所生成的文件是ply格式的,里面包含了

element face这个重要信息。

大部分大佬的教程是先将ply文件转为pcd文件,再将pcd文件合并之后再次转移成为ply文件,但是

利用PCLPointCloud2转变后的ply文件丢失了element face的数量和具体的索引。

所以可以利用PolygonMesh将ply文件读取之后进行合并。(利用 PolygonMesh.concatenate()即可。)

但是利用该函数合并之后的索引信息是有bug的, 他对索引信息值直接会增加全部点云数量的值(假设mesh1和mesh2分别有10个和20个值,那么在合并后的mesh3文件后面的索引信息中,mesh2的索引信息值不是从20开始,反而变成从30开始,导致索引错误,那么拼接之后的模型是显示不成功的)。

下面贴上对应的解决方法,由于时间有点急,写的比较乱,整体思路就是把合并之后的mesh3文件后面的索引信息值进行修改,利用的也就是c++中简单的文件读和写操作。

int contenate_ply()
{
    pcl::PolygonMesh mesh1;
    pcl::io::loadPLYFile("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-1.ply", mesh1);
    pcl::PolygonMesh mesh2;
    pcl::io::loadPLYFile("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-2.ply", mesh2);
    pcl::PolygonMesh  mesh3;
    mesh3.concatenate(mesh1, mesh2, mesh3);
    pcl::io::savePLYFile("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D.ply", mesh3);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPLYFile<pcl::PointXYZ>("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-1.ply", *cloud1);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPLYFile<pcl::PointXYZ>("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-2.ply", *cloud2);
    int sum = cloud1->points.size();
    cout << "point_1_number:" << sum << endl;
    rename("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-1.ply", "C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-1.txt");

    fstream fin("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-1.txt", ios::in);
    if (!fin)
    {
        cerr << "can not open file" << endl;
        return -1;
    }

    char c1;
    int lineCnt = 0;
    while (fin.get(c1))
    {
        if (c1 == '\n')
            lineCnt++;
    }
    cout << lineCnt + 1 + cloud2->points.size() << endl;
    int total = lineCnt + 1 + cloud2->points.size();
    fin.close();
    rename("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-1.txt", "C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D-1.ply");
    rename("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D.ply", "C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D.txt");
    fstream fin1("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D.txt", ios::in);
    if (!fin1)
    {
        cerr << "can not open file" << endl;
        return -1;
    }
    char cc;
    lineCnt = 0;
    while (fin1.get(cc))
    {
        if (cc == '\n')
            lineCnt++;
    }
    cout << lineCnt + 1 << endl;
    int txttotal = lineCnt + 1;
    fin1.close();
    std::queue<int> a;
    std::queue<int> b;
    std::queue<int> c;
    std::queue<int> d;

    ifstream f;//读权限变量 f
    std::queue<std::string> r;//用于存储
    f.open("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D.txt");//文件text需要存放在当前cpp文件的根目录中
    std::string linee, s;
    int txtLine = 1;
    while (getline(f, linee))        //从文件中读取一行存放在line中
    {
        int  aaa, bbb, ccc, ddd;
        r.push(linee);
        if (txtLine >= total && txtLine < txttotal)
        {
            std::istringstream is(linee);
            is >> aaa >> bbb >> ccc >> ddd;
            cout << aaa << " " << bbb << " " << ccc << "" << ddd << endl;
            a.push(aaa);
            b.push(bbb);
            c.push(ccc);
            d.push(ddd);
        }
        txtLine++;
    }
    ifstream in;
    in.open("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D.txt");
    std::string strFileData = "";
    int line = 1;
    char tmpLineData[1024] = { 0 };
    while (in.getline(tmpLineData, sizeof(tmpLineData)))
    {
        if (line >= total && line < txttotal)
        {
            strFileData += std::string("3 " + std::to_string(b.front() - cloud2->points.size()) + " " + std::to_string(c.front() - cloud2->points.size()) + " " + std::to_string(d.front() - cloud2->points.size()));
            strFileData += "\n";
            b.pop();
            c.pop();
            d.pop();
        }
        else
        {
            strFileData += std::string(tmpLineData);
            strFileData += "\n";
        }
        line++;
    }
    in.close();
    //写入文件
    ofstream out;
    out.open("C:\\Users\\A\\Desktop\\c\\A10-16008\\mesh3D.txt");
    out.flush();
    out << strFileData;
    out.close();
}

效果如下

 

 这两个要进行拼接的ply文件展示图

 

欢迎各位做pcl的大牛们指点交流

举报

相关推荐

0 条评论