ply 又稱多邊形檔案(Polygon File Format)或史丹佛三角形檔案(Stanford Triangle Format),是一種儲存 3D 模型的檔案格式。
ply 格式改進了 obj 格式所缺少對任意屬性及群組的擴充性,因此發明了 element 和 property 這兩個關鍵字,來概括「頂點、面、相關資訊、群組」的概念。
以 ply 開頭作為該格式的識別。
ply
接著第二行是版本資訊,有 ASCII 與 Binary 兩種版本。
format ascii 1.0
註解使用 comment
關鍵字作為一行的開頭。
comment This is a comment!
用 header 來設定網格模型的 element
與 property
。
使用 end_header
來表示 header 的結束。
header 定義結束後,下方接著一連串 element 所定義 property 的 value
。
在定義 element 後,下方接著需要的 property。可以用 C 語言的 structure 來理解。
element vertex 8
property float32 x
property float32 y
property float32 z
vertex
, face
char
, uchar
, short
, ushort
, int
, uint
, float
, double
int8
, uint8
, int16
, uint16
, int32
, uint32
, float32
, float64
x
, y
, z
, vertex_index
property 同時也是定義屬性資料出現的順序,例如需要按照 x, y, z 的順序填寫資料。
對於元素 face 而言,一個面試由 3 個以上的頂點組成,因此需要由一個列表組成,使用 property list
關鍵字定義。
element face 12
property list uint8 int32 vertex_index
上述範例敘述該檔案中會有一個 element_name 為 face 的元素 12 個,並且該元素的屬性是一個清單列表,分別由 uint 型態的數值表示列表會有幾項,後面接著型態為 int32 的頂點索引值(vertex_index),頂點索引值從 0 開始。
<aside> 💡 可能會有一個疑問是,為甚麼需要記錄列表有幾項?不是看一行到結束符號前有多少數值判斷即可?這個原因可以從檔案格式方面解釋,在 ASCII 格式中可以將資訊以獨立的一行描述,但如果使用 binary 格式儲存這些資料時,資料都是以同一行來解釋,因此需要直接以 element 定義個元素數目來判斷各個資料的長度。
</aside>
element 同時也是定義元素資料出現的順序,例如有多個 element 時,需要按照順序敘述 element 的 value。
一個典型的 ply 檔案結構可以分成三部分:
檔案標頭(從 ply 開始到 end_header)
頂點元素列表
面元素列表
其中頂點元素列表以 x y z 方式排列,型態如同 header 所定義。而面元素列表如以下格式
<組成面的頂點數 N> <頂點 #1 的索引> <頂點 #2 的索引> ... <頂點 #N 的索引>
一個正方體
ply
format ascii 1.0
comment made by anonymous
comment this file is a cube
element vertex 8
property float32 x
property float32 y
property float32 z
element face 12
property list uint8 int32 vertex_index
end_header
0 0 0
0 25.8 0
18.9 0 0
18.9 25.8 0
0 0 7.5
0 25.8 7.5
18.9 0 7.5
18.9 25.8 7.5
3 5 1 0
3 5 4 0
3 4 0 2
3 4 6 2
3 7 5 4
3 7 6 4
3 3 2 1
3 1 2 0
3 5 7 1
3 7 1 3
3 7 6 3
3 6 3 2
一個三角體
ply
format ascii 1.0
comment 這是一個三角體
element vertex 4
property float x
property float y
property float z
element face 4
property list uchar int vertex_index
end_header
0 3 0
2.449 -1.0 -1.414
0 -1 2.828
-2.449 -1.0 -1.414
3 0 1 3
3 0 2 1
3 0 3 2
3 1 2 3