您好,欢迎访问三七文档
ply格式总结一、ply格式简介PLY文件格式是Stanford大学开发的一套三维mesh模型数据格式,图形学领域内很多著名的模型数据,比如Stanford的三维扫描数据库(其中包括很多文章中会见到的HappyBuddha,Dragon,Bunny兔子),GeogiaTech的大型几何模型库,北卡(UNC)的电厂模型等,最初的模型都是基于这个格式的。PLY作为一种多边形模型数据格式,不同于三维引擎中常用的场景图文件格式和脚本文件,每个PLY文件只用于描述一个多边形模型对象(Object),该模型对象可以通过诸如顶点、面等数据进行描述,每一类这样的数据被称作一种元素(Element)。二、ply格式1、PLY的文件结构简单:文件头加上元素数据列表。其中文件头中以行为单位描述文件类型、格式与版本、元素类型、元素的属性等,然后就根据在文件头中所列出元素类型的顺序及其属性,依次记录各个元素的属性数据。2、典型的PLY文件结构:头部顶点列表面片列表(其他元素列表)3、举例ply{头部的开始,是文件的识别字符}formatascii1.0{关键词format,特定的ascii或二进制格式(见说明1),版本号}commentmadebyanonymous{关键词comment,要注释的内容。}commentthisfileisacube{注释内容可有可无}elementvertex8{描述一个元素开始:关键词element,元素名,元素在文件中的个数}propertyfloat32x{元素属性:关键词property,数据类型(见说明2),属性名}propertyfloat32ypropertyfloat32zelementface6{第二个元素}propertylistuint8int32vertex_index{列表数据类型,见说明3}end_header{结尾,与ply呼应}{以上是头部的全部内容}{顶点列表开始}000001011010100101111110{面片列表开始:顶点个数,顶点索引号}401234765440451415624267343740说明:1.例子中文件使用的是ascii,二进制版本头部的唯一不同是用词“binary_little_endian”或者“binary_big_endian”替换词“ascii”。2.属性可能具有的标量数据类型列表如下:名称类型字节数-------------------------------int8字符1uint8非负字符1int16短整型2uint16非负短整型2int32整型4uint32非负整型4float32单精度浮点数4float64双精度浮点数83.列表数据类型的属性定义有一种特殊的格式:propertylist数值类型数值类型属性名这种格式的一类例子是上面文件中的:propertylistuint8int32vertex_index这表示属性“vertex_index”首先包含一个非负字符报苏在属性里包含多少索引,接下来是一个列表包含许多整数。在这个边长列表里的每个整数都是一个顶点的索引。三、ply格式的读写1.首先是所需数据结构的定义(1)点结构structPoint3d{public:floatX;floatY;floatZ;Point3d(floatx,floaty,floatz){this-X=x;this-Y=y;this-Z=z;}};(2)三角形结构三角形结构按常理理解应该是包含了3个Point3d,不过这里有两种方式来定义这个Triangle结构。一种是采用点地址:structTriangle{public:Point3d*P0;Point3d*P1;Point3d*P2;Triangle(Point3d*p0,Point3d*p1,Point3d*p2){this-P0=p0;this-P1=p1;this-P2=p2;}};第二种是使用索引:structTriangle{public:intP0Index;intP1Index;intP2Index;Triangle(intp0index,intp1index,intp2index){this-P0Index=p0index;this-P1Index=p1index;this-P2Index=p2index;}};(3)mesh结构classMesh{public:std::vectorPoint3d*Vertices;std::vectorTriangle*Faces;Mesh();~Mesh();voidAddVertex(Point3d*toAdd);voidAddFace(Triangle*tri);};classMesh{public:std::vectorPoint3dVertices;std::vectorTriangleFaces;Mesh();~Mesh();voidAddVertex(Point3d&toAdd);voidAddFace(Triangle&tri);};2.使用这里定义的Mesh类,使用C++语言读写.ply文件的函数如下:(1)ply文件的读voidReadFile(Mesh&mesh,constchar*fileName){intvcount=0;intfcount=0;FILE*nfile=fopen(fileName,r);fscanf(nfile,ply\nformatascii1.0\ncommentVCGLIBgenerated\nelementvertex%d\n,&vcount);fscanf(nfile,propertyfloatx\npropertyfloaty\npropertyfloatz\npropertyucharred\npropertyuchargreen\npropertyucharblue\nelementface%d\n,&fcount);fscanf(nfile,propertylistintintvertex_indices\nend_header\n);floatv1=0,v2=0,v3=0;intr=0,g=0,b=0;inti1=0,i2=0,i3=0;for(inti=0;ivcount;i++){fscanf(nfile,%f%f%f%d%d%d\n,&v1,&v2,&v3,&r,&g,&b);Point3dp3d(v1,v2,v3);mesh.AddVertex(p3d);}for(intj=0;jfcount;j++){fscanf(nfile,3%d%d%d\n,&i1,&i2,&i3);Trianglet(i1,i2,i3);mesh.AddFace(t);}fclose(nfile);}(2)ply文件的写voidOutput(Mesh&mesh,constchar*filename){FILE*nfile=fopen(filename,wb);fprintf(nfile,ply\n);fprintf(nfile,formatascii1.0\n);fprintf(nfile,commentVCGLIBgenerated\n);fprintf(nfile,elementvertex%d\n,mesh.Vertices.size());fprintf(nfile,propertyfloatx\n);fprintf(nfile,propertyfloaty\n);fprintf(nfile,propertyfloatz\n);fprintf(nfile,propertyucharred\n);fprintf(nfile,propertyuchargreen\n);fprintf(nfile,propertyucharblue\n);fprintf(nfile,elementface%d\n,mesh.Faces.size());fprintf(nfile,propertylistintintvertex_indices\n);fprintf(nfile,end_header\n);for(size_ti=0;imesh.Vertices.size();i++){fprintf(nfile,%.2f%.2f%.2f%d%d%d\n,mesh.Vertices[i].Data[0],mesh.Vertices[i].Data[1],mesh.Vertices[i].Data[2],255,255,255);}for(size_ti=0;imesh.Faces.size();i++){fprintf(nfile,%d%d%d%d\n,3,mesh.Faces[i].P0Index,mesh.Faces[i].P1Index,mesh.Faces[i].P2Index);}fclose(nfile);}
本文标题:ply格式相关内容
链接地址:https://www.777doc.com/doc-2851609 .html