本文介紹PLY 多邊形文件格式,這是一種用于存儲被描述為多邊形集合的圖形對象。 PLY文件格式的目標是提供一種簡單且易于實現但通用的格式足以適用于各種模型。 PLY有兩種子格式:易于入門的 ASCII 表示形式和用于緊湊存儲和快速保存和加載的二進制格式。 我們希望這種格式將促進程序之間以及人群之間的圖形對象的交換。
如果需要將gltf、fbx、obj、dae等格式的3D模型轉換到PLY格式,可以使用這個在線的 3D模型格式轉換 工具。
1、PLY格式概述
任何在計算機圖形領域工作過一段時間的人時間知道圖形存儲格式的令人眼花繚亂的陣列對象。 似乎每個程序員、每個新的編程項目都創建一種新的文件格式。
走出這個泥沼的出路是創建一個足夠靈活的單一文件格式預測未來的需求,這很簡單,以免被趕走潛在用戶。 一旦定義了這樣的格式,就會出現一套實用程序可以圍繞這個格式編寫。 添加到套件中的每個新實用程序都可以利用其他人的成果。
PLY 格式將對象描述為頂點、面和其他元素,以及顏色和法線方向等可以附加到這些元素上的屬性。PLY 文件包含恰好是一個對象的以下描述。
此類對象的來源包括:手工數字化對象,來自建模程序的多邊形對象、范圍數據、行進立方體三角化(體積數據的等值面)、地形數據、光能傳遞模型等。
可能與對象一起存儲的屬性包括:顏色、表面法線、紋理坐標、透明度、范圍數據置信度,以及多邊形正面和背面的不同屬性。
PLY 格式并非旨在作為一般場景描述語言、著色語言或包羅萬象的建模格式。 這意味著它不包括變換矩陣、對象實例化、建模層次結構或對象子部分。
典型的 PLY 對象定義只是 (x,y,z) 三元組的頂點列表和面列表,由列表中的索引描述頂點。 大多數 PLY 文件都包含此核心信息。 頂點和面是“元素”的兩個示例,PLY 文件的大部分內容是其列表元素。 給定文件中的每個元素都有固定數量的“屬性”
為每個元素指定。
PLY 文件中的典型信息只包含兩個元素,頂點的 (x,y,z) 三元組和每個面的頂點索引。 應用程序可以創建附加到對象元素的新屬性。 例如,紅色、綠色和藍色的屬性通常與頂點元素相關。 添加新的屬性時,舊程序不應被中斷,解釋不了的可以被丟棄。
此外,還可以創建一個新元素類型并定義與該元素關聯的屬性。 新元素的例子是邊、單元(指向面的指針列表)和材質(環境、漫反射和鏡面反射顏色和系數)。 新元素還可以被不理解它們的程序攜帶或丟棄。
2、PLY文件結構
這是典型 PLY 文件的結構:
- 標頭
- 頂點列表
- 面列表
- 其他元素的列表
標頭是一系列以回車符結尾的文本行,描述文件的其余部分。 標頭包含每個的描述
元素類型,包括元素的名稱(例如 edge),有多少個這樣的元素位于對象中,以及關聯的各種屬性的列表與元素。 標頭還表明該文件是二進制文件還是 ASCII 文件。標頭后面是每種元素類型的元素列表,按照表頭中描述的順序出現。
以下是一個立方體模型的完整 ASCII 描述。 同一對象的二進制文件的標頭
僅僅是用 binary_little_endian或 binary_big_endian 代表單詞 ascii。 這
括號中的注釋不是文件的一部分,它們是對此示例的注釋。 文件中的注釋是普通的關鍵字標識行,以 comment 開頭。
ply
format ascii 1.0 { ascii/binary, format version number }
comment made by anonymous { comments keyword specified, like all lines }
comment this file is a cube
element vertex 8 { define "vertex" element, 8 of them in file }
property float32 x { vertex contains float "x" coordinate }
property float32 y { y coordinate is also a vertex property }
property float32 z { z coordinate, too }
element face 6 { there are 6 "face" elements in the file }
property list uint8 int32 vertex_index { "vertex_indices" is a list of ints }
end_header { delimits the end of the header }
0 0 0 { start of vertex list }
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
4 0 1 2 3 { start of face list }
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
這個示例演示了標頭的基本組成部分。 各部分標頭是一個以關鍵詞開頭、以回車符結尾的 ASCII 字符串,甚至標題的開始和結束( ply和 end_header)也采用這種形式。
字符 ply必須是文件的前四個字符,因為它們是文件的魔力數字。 標題開頭之后是關鍵字 format和ASCII 或二進制格式的規范,后跟版本數字。 接下來是多邊形中各個元素的描述,并且在每個元素描述中是規范特性。 通用元素描述具有以下形式:
element <element-name> <number-in-file>
property <data-type> <property-name-1>
property <data-type> <property-name-2>
property <data-type> <property-name-3>
...
element行后面列出的屬性定義了屬性的數據類型以及該屬性在每個元素中出現的順序。屬性可能具有三種數據類型:標量、字符串和列表。 以下是屬性可能具有的標量數據類型的列表:
name | type | number of bytes |
---|---|---|
int8 | character | 1 |
uint8 | unsigned character | 1 |
int16 | short integer | 2 |
uint16 | unsigned short integer | 2 |
int32 | integer | 4 |
uint32 | unsigned integer | 4 |
float32 | single-precision float | 4 |
float64 | double-precision float | 8 |
這些字節數很重要,并且在不同的實現中不得有所不同以保證這些文件可移植。 有一種特殊形式的屬性定義使用列表數據類型:
property list <numerical-type> <numerical-type> <property-name>
上面的立方體數據集文件中的一個示例:
property list uint8 int32 vertex_index
這意味著屬性 vertex_index 首先包含一個無符號字符標識屬性包含多少個索引,后跟一個包含的證書列表。 這個可變長度列表中的每個整數都是一個頂點的索引。
3、PLY文件的另一個例子
這是另一個立方體定義:
ply
format ascii 1.0
comment author: anonymous
comment object: another cube
element vertex 8
property float32 x
property float32 y
property float32 z
property red uint8 { start of vertex color }
property green uint8
property blue uint8
element face 7
property list uint8 int32 vertex_index { number of vertices for each face }
element edge 5 { five edges in object }
property int32 vertex1 { index to first vertex of edge }
property int32 vertex2 { index to second vertex }
property uint8 red { start of edge color }
property uint8 green
property uint8 blue
end_header
0 0 0 255 0 0 { start of vertex list }
0 0 1 255 0 0
0 1 1 255 0 0
0 1 0 255 0 0
1 0 0 0 0 255
1 0 1 0 0 255
1 1 1 0 0 255
1 1 0 0 0 255
3 0 1 2 { start of face list, begin with a triangle }
3 0 2 3 { another triangle }
4 7 6 5 4 { now some quadrilaterals }
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
0 1 255 255 255 { start of edge list, begin with white edge }
1 2 255 255 255
2 3 255 255 255
3 0 255 255 255
2 0 0 0 0 { end with a single black line }
該文件為每個頂點指定紅色、綠色和藍色值。 為說明 vertex_index 的可變長度性質,對象的前兩個面是三角形而不是正方形。 這意味著對象的面數為 7。
該對象還包含一個邊的列表。 每條邊都包含兩個指向邊的頂點的指針。 每個邊也有一種顏色。 上面定義的五個邊突出顯示文件中的兩個三角形。 前4條邊是白色的,它們圍繞著兩個三角形。 最終的邊是黑色,它是分隔三角形的邊。
4、PLY自定義元素
上面的例子展示了三個元素的使用:頂點、面和邊。 PLY 格式還允許用戶定義自己的元素。
定義新元素的格式與定義頂點、邊和面完全相同。 這是定義材質屬性的標頭:
element material 6
property ambient_red uint8 { ambient color }
property ambient_green uint8
property ambient_blue uint8
property ambient_coeff float32
property diffuse_red uint8 { diffuse color }
property diffuse_green uint8
property diffuse_blue uint8
property diffuse_coeff float32
property specular_red uint8 { specular color }
property specular_green uint8
property specular_blue uint8
property specular_coeff float32
property specular_power float32 { Phong power }
這些行將直接出現在標題中的頂點、面和邊的規范之后。 如果我們希望每個頂點都有一個材質,我們可以將此行添加到頂點屬性的末尾:
property material_index int32
這個整數是文件中包含的材質列表的索引。對于一個新應用程序的作者來說,發明幾個要存儲在 PLY 文件中的元素可能很吸引人。這種做法應該保持克制。 更好的方法是嘗試調整常見元素(頂點、面、邊、材質)到新用途,以便其他理解這些的程序elements 可能有助于操作這些元素。
例如,一個將分子描述為球體和柱體集合的應用程序, 為PLY增加包含分子的 球體和圓柱體元素的定義是很誘人的。 但是,如果我們使用頂點和邊為此目的的元素(為每個元素添加半徑屬性),我們可以繼續這些舊的程序。 顯然不應為三角形和四邊形創建特殊元素,而是使用face 元素。
原文鏈接:原文鏈接 — BimAnt