81.1 引入
在“Q79”和“Q80”中用三角形网格细分曲面时,都是将每一个三角形的三个顶点的坐标都保存在内存中。这句话有两个重点:
其一,每个三角形的三个顶点的坐标都计算了一次。但是,每个顶点都是被好几个三角形公用的,所以每个顶点的坐标被重复计算了好几次。
其二,所有顶点的坐标都是临时计算的,然后保存到内存中的。如果顶点数量特别大(百万级、千万级),这样临时计算则会导致程序运行缓慢。是否可先将顶点的坐标都算好保存在文件中,程序运行时直接读这个文件就可以了呢?
这种保存“将图形用三角形网格细分后得到的三角形信息”的文件被称为“PLY文件”。
81.2 PLY文件的格式
PLY文件由两部分组成:文件头、文件体。
文件头是由以“回车(carriage-return)”为结束符的ASCII字符串组成的。
文件体是由“元素”组成。一般情况,会包含两类“元素”:第一类,顶点信息(含顶点的坐标值、法向量、纹理映射值等等);第二类,多边形各个顶点在第一类元素中的索引值。
如下方示意:
PLY文件的内容是非常灵活的。第一类元素“顶点vertex”,除了可以包含顶点的坐标值,还可以包含顶点的“法向量”、“纹理坐标”、“颜色值”等等;第二类元素“face”,其实是可以表示任意多边形的,而且不同顶点数的各种多边形可以同时被包含在同一个PLY文件中。
81.3 将经典的PLY文件从Unix/Mac系统下的格式转换到Windows系统下的格式
参考:
http://blog.csdn.net/libing_zeng/article/details/60878097
转换后的PLY文件截图如下:
这些文件的路径:http://download.csdn.net/detail/libing_zeng/9775786
81.4 程序读取PLY文件
Greg Turk发明PLY文件格式之后,就有提供通用的可拓展的读取PLY文件的程序。相关链接如下:http://www.cc.gatech.edu/projects/large_models/ply.html
但是,本人是直接移植了《Ray Tracing from the Ground Up》的相关代码。在移植过程中遇到两个问题:
《Ray Tracing from the Ground Up》中提供的调用读取PLY文件接口的函数如下:
// ----------------------------------------------------------------------------- read_ply_file
// Most of this function was written by Greg Turk and is released under the licence agreement
// at the start of the PLY.h and PLY.c files
// The PLY.h file is #included at the start of this file
// It still has some of his printf statements for debugging
// I've made changes to construct mesh triangles and store them in the grid
// mesh_ptr is a data member of Grid
// objects is a data member of Compound
// triangle_type is either flat or smooth
// Using the one function construct to flat and smooth triangles saves a lot of repeated code
// The ply file is the same for flat and smooth triangles
void
Grid::read_ply_file(char* file_name, const int triangle_type) {
// Vertex definition
typedef struct Vertex {
float x,y,z; // space coordinates
} Vertex;
// Face definition. This is the same for all files but is placed here to keep all the definitions together
typedef struct Face {
unsigned char nverts; // number of vertex indices in list
int* verts; // vertex index list
} Face;
// list of property information for a vertex
// this varies depending on what you are reading from the file
PlyProperty vert_props[] = {
{"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0},
{"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0},
{"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0}
};
// list of property information for a face.
// there is a single property, which is a list
// this is the same for all files
PlyProperty face_props[] = {
{"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts),
1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)}
};
// local variables
int i,j;
PlyFile* ply;
int nelems; // number of element types: 2 in our case - vertices