Code Yarns ‍👨‍💻
Tech BlogPersonal Blog

Output 3D Mesh to PLY File

📅 2011-Aug-18 ⬩ ✍️ Ashwin Nanjappa ⬩ 📚 Archive

The PLY file format is one of the simplest ways to read and write a 3D mesh. There are a few libraries which can be used to read or write PLY files from your code.

However, if you are dealing with a simple triangulated 3D mesh, there is no need to use a library. Writing such a mesh out to a PLY file from your code is very simple. Here is sample code in C++:

#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

struct Point
{
    float _p[ 3 ];
};

typedef vector< Point > PointVec;

struct Triangle
{
    float _v[ 3 ];
};

typedef vector< Triangle > TriangleVec;

void writeMeshToPLYFile
(
const PointVec&    pointVec,
const TriangleVec& triangleVec,
const string&      outFilename
)
{
    ofstream outFile( outFilename.c_str() );

    if ( !outFile )
    {
        cerr << "Error opening output file: " << outFilename << "!" << endl;
        exit( 1 );
    }

    ////
    // Header
    ////

    const int pointNum    = ( int ) pointVec.size();
    const int triangleNum = ( int ) triangleVec.size();

    outFile << "ply" << endl;
    outFile << "format ascii 1.0" << endl;
    outFile << "element vertex " << pointNum << endl;
    outFile << "property float x" << endl;
    outFile << "property float y" << endl;
    outFile << "property float z" << endl;
    outFile << "element face " << triangleNum << endl;
    outFile << "property list uchar int vertex_index" << endl;
    outFile << "end_header" << endl;

    ////
    // Points
    ////

    for ( int pi = 0; pi < pointNum; ++pi )
    {
        const Point& point = pointVec[ pi ];

        for ( int vi = 0; vi < 3; ++vi )
            outFile << point._p[ vi ] << " ";

        outFile << endl;
    }

    ////
    // Triangles
    ////

    for ( int ti = 0; ti < triangleNum; ++ti )
    {
        const Triangle& triangle = triangleVec[ ti ];
        outFile << "3 ";

        for ( int vi = 0; vi < 3; ++vi )
            outFile << triangle._v[ vi ] << " ";

        outFile << endl;
    }

    return;
}