文章目录
- 引言
- off格式文件
- ply格式文件
- C++标准库实现off转ply
引言
三维模型是计算机图形学中的一个重要概念,它是由一系列三维坐标点构成的点云或多边形网格。
 OFF格式是一种用于描述三维模型的文件格式,它可以描述点云和多边形网格等不同类型的三维模型。
 PLY是一种三维mesh模型数据格式,全名为多边形档案(Polygon File Format)或斯坦福档案。是Stanford大学开发的一套三维mesh模型数据格式,图形学领域内非常多著名的模型数据,比方Stanford的三维扫描数据库,Geogia Tech的大型几何模型库等,最初的模型都是基于这个格式的。
off格式文件
OFF(Object File Format)格式是一种简单的三维模型描述文件格式,它由三部分组成:文件头、点坐标和面索引。
 文件头:包含模型的基本信息,如点数、面数等。
 点坐标:包含模型的点坐标信息,每行包含了一个点的三维坐标信息。
 面索引:包含模型的面信息,每行包含了一个面的顶点索引信息。
ply格式文件
ply主要用以存储立体扫描结果的三维数值,通过多边形片面的集合描述三维物体。它可以存储的信息包含:颜色、透明度、表面法向量、材质坐标与信息的可信度,并能对多边形的正反两面设定不同的属性。
 在数据内容存储上PLY有两种版本:纯文字(ASCII)版本与二进制(binary)版本
C++标准库实现off转ply
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
//定义结构体Vertex,表示顶点的x、y、z坐标
struct Vertex {
    float x, y, z;
};
//定义结构体Face,表示面的三个顶点索引
struct Face {
    int v1, v2, v3;
};
void offToPly(const std::string& inputFileName, const std::string& outputFileName) {
    std::ifstream inputFile(inputFileName);
    if (!inputFile.is_open()) {
        std::cerr << "Error: Unable to open input file " << inputFileName << std::endl;
        return;
    }
    std::ofstream outputFile(outputFileName);
    if (!outputFile.is_open()) {
        std::cerr << "Error: Unable to create output file " << outputFileName << std::endl;
        return;
    }
    //从输入文件中,读取文件格式,顶点数量,面数量和边数量
    std::string format;
    int numVertices, numFaces, numEdges;
    inputFile >> format >> numVertices >> numFaces >> numEdges;
    if (format != "OFF") {
        std::cerr << "Error: Input file is not in OFF format" << std::endl;
        return;
    }
//创建存储顶点的向量
std::vector<Vertex> vertices(numVertices);
    for (int i = 0; i < numVertices; ++i) {
        inputFile >> vertices[i].x >> vertices[i].y >> vertices[i].z;
    }
//创建存储面的向量
std::vector<Face> faces(numFaces);
    for (int i = 0; i < numFaces; ++i) {
        int numVerticesInFace;
        inputFile >> numVerticesInFace;
        if (numVerticesInFace != 3) {
            std::cerr << "Error: Only triangular faces are supported" << std::endl;
            return;
        }
        inputFile >> faces[i].v1 >> faces[i].v2 >> faces[i].v3;
    }
    //打开输出文件后,写入PLY文件的头部信息,包括文件格式、顶点和面的数量
    outputFile << "ply" << std::endl;
    outputFile << "format ascii 1.0" << std::endl;
    outputFile << "element vertex " << numVertices << std::endl;
    outputFile << "property float x" << std::endl;
    outputFile << "property float y" << std::endl;
    outputFile << "property float z" << std::endl;
    outputFile << "element face " << numFaces << std::endl;
    outputFile << "property list uchar int vertex_indices" << std::endl;
    outputFile << "end_header" << std::endl;
    //将顶点向量中的坐标写入输出文件
    for (const Vertex& vertex : vertices) {
        outputFile << vertex.x << " " << vertex.y << " " << vertex.z << std::endl;
    }
    //将面向量中的坐标写入输出文件
    for (const Face& face : faces) {
        outputFile << "3 " << face.v1 << " " << face.v2 << " " << face.v3 << std::endl;
    }
    std::cout << "Conversion complete. Output saved to " << outputFileName << std::endl;
}
int main() {
    const std::string inputFileName = "E:\\.off";   
    const std::string outputFileName = "E:\\.ply"; 
    offToPly(inputFileName, outputFileName);
    return 0;
}




















