tak0kadaの何でもノート

発声練習、生存確認用。

医学関連は 医学ノート

plyファイルをc++で開く

GitHub - nmwsharp/happly: A C++ header-only parser for the PLY file format. Parse .ply happily!を使えば簡単にデータを取り出せて便利。

#include <algorithm>
#include <iostream>
#include <exception>
#include "happly/happly.h"
#include "cnthd/mesh.hpp"

int main()
{
    happly::PLYData plyIn("./sphere.ply");
    try
    {
        plyIn.validate();
    }
    catch (const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    const std::vector<std::array<double, 3>> vertex = plyIn.getVertexPositions();
    const std::vector<std::vector<std::size_t>> face_tmp = plyIn.getFaceIndices();
    std::vector<std::array<std::size_t, 3>> face(face_tmp.size());

    std::transform(face_tmp.begin(), face_tmp.end(), face.begin(),
        [](const std::vector<std::size_t>& f) -> std::array<std::size_t, 3>
            { return {f[0], f[1], f[2]}; }
        );

    cnthd::Mesh mesh(vertex, face);
    cnthd::write_obj(mesh, "./sphere.obj");
 
    return 0;
}

追記: ヘッダーの内容によっては開けないらしいので、その行だけ適当なコメントに置換することにした。(eg: obj_info vtkPolyData points and polygons: vtk4.0comment aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa )

import mmap
import os

fd = os.open("./input.ply")
size = os.path.getsize("./input.ply")
mm = mmap.mmap(fd, size)
# 問題がある行まで読み飛ばす
mm.readline(), mm.readline(), mm.readline()
byte = ( "comment " + "a" * (mm.find(b'\n') - mm.tell() - 8) ).encode("latin-1")
mm.write(byte)
mm.flush()
mm.close()