OBJ檔案格式詳解

來源:互聯網
上載者:User

    OBJ檔案是Alias|Wavefront公司為它的一套基於工作站的3D建模和動畫軟體"Advanced Visualizer"開發的一種標準3D模型檔案格式,很適合用於3D軟體模型之間的互導,也可以通過Maya讀寫。比如你在3dsMax或LightWave中建了一個模型,想把它調到Maya裡面渲染或動畫,匯出OBJ檔案就是一種很好的選擇。目前幾乎所有知名的3D軟體都支援OBJ檔案的讀寫,不過其中很多需要通過外掛程式才能實現。
    OBJ檔案是一種文字檔,可以直接用寫字板開啟進行查看和編輯修改。另外,有一種與此相關二進位檔案格式(*.MOD),其作為專利未公開,因此這裡不作討論。

1、OBJ檔案的特點

    OBJ3.0檔案格式支援直線(Line)、多邊形(Polygon)、表面(Surface)和自由形態曲線(Free-form Curve)。直線和多邊形通過它們的點來描述,曲線和表面則根據它們的控制點和依附於曲線類型的額外資訊來定義,這些資訊支援規則和不規則的曲線,包括那些基於貝茲路徑(Bezier)、B樣條(B-spline)、基數(Cardinal/Catmull-Rom)和泰勒方程(Taylor equations)的曲線。其他特點如下:

(1)OBJ檔案是一種3D模型檔案。不包含動畫、材質特性、貼圖路徑、動力學、粒子等資訊。
(2)OBJ檔案主要支援多邊形(Polygons)模型。雖然也支援曲線(Curves)、表面(Surfaces)、點組材質(Point Group Materials),但Maya匯出的OBJ檔案並不包括這些資訊。
(3)OBJ檔案支援三個點以上的面,這一點很有用。很多其它的模型檔案格式只支援三個點的面,所以匯入Maya的模型經常被三角化了,這對於我們對模型進行再加工甚為不利。 
(4)OBJ檔案支援法線和貼圖座標。在其它軟體中調整好貼圖後,貼圖座標資訊可以存入OBJ檔案中,這樣檔案匯入Maya後只需指定一下貼圖檔案路徑就行了,不需要再調整貼圖座標。
 

2、OBJ檔案的基本結構
    OBJ檔案不需要任何種檔案頭(File Header),儘管經常使用幾行檔案資訊的注釋作為檔案的開頭。OBJ檔案由一行行文本組成,注釋行以符號“#”為開頭,空格和空行可以隨意加到檔案中以增加檔案的可讀性。有字的行都由一兩個標記字母也就是關鍵字(Keyword)開頭,關鍵字可以說明這一行是什麼樣的資料。多行可以邏輯地串連在一起表示一行,方法是在每一行最後添加一個串連符(\)。 注意串連符(\)後面不能出現空格或Tab格,否則將導致檔案出錯。

下列關鍵字可以在OBJ檔案使用。在這個列表中, 關鍵字根據資料類型排列,每個關鍵字有一段簡短描述。

頂點資料(Vertex data):
          v 幾何體頂點(Geometric vertices)
           vt 貼圖座標點(Texture vertices)
           vn 頂點法線(Vertex normals)
           vp 參數空格頂點 (Parameter space vertices)

自由形態曲線(Free-form curve)/表面屬性(surface attributes):
   deg   度(Degree)
     bmat   基礎矩陣(Basis matrix)
      step   步尺寸(Step size)
     cstype 曲線或表面類型 (Curve or surface type)

元素(Elements):
        p  點(Point)
             l  線(Line)
             f  面(Face)
        curv  曲線(Curve)
      curv2  2D曲線(2D curve)
         surf  表面(Surface)

自由形態曲線(Free-form curve)/表面主體陳述(surface body statements):
        parm 參數值(Parameter values )
          trim 外部修剪迴圈(Outer trimming loop)
          hole 內部整修迴圈(Inner trimming loop)
          scrv 特殊曲線(Special curve)
             sp 特殊的點(Special point)
          end  結束陳述(End statement)

自由形態表面之間的串連(Connectivity between free-form surfaces):
         
con 串連 (Connect)

成組(Grouping):
              g  組名稱(Group name)
               s 光滑組(Smoothing group)
            mg 合并組(Merging group)
               o 對象名稱(Object name)

顯示(Display)/渲染屬性(render attributes):
      bevel 導角插值(Bevel interpolation)
       c_interp 顏色插值(Color interpolation)
       d_interp 溶解插值(Dissolve interpolation)
               lod 細節層次(Level of detail)
         usemtl 材質名稱(Material name)
           mtllib 材質庫(Material library)
 shadow_obj  投射陰影(Shadow casting)
     trace_obj  光線跟蹤(Ray tracing)
           ctech  曲線近似技術(Curve approximation technique)
           stech  表面近似技術 (Surface approximation technique)

3、OBJ檔案執行個體
    的確挺難理解,下面通過執行個體來具體講解。讓我們來建立一個OBJ檔案,內容為一個四邊形,不過這一回我們不用3D軟體,而是用寫字板來建立。開啟寫字板,把下面的5行代碼寫入,可以適當加一點注釋。儲存檔案為文字格式設定,檔案名稱為"myObj.obj"。

   v -0.58 0.84 0   v 2.68 1.17 0   v 2.84 -2.03 0   v -1.92 -2.89 0   f 1 2 3 4
    注意:代碼最後一定要按一下斷行符號把游標切換到下一行,就是說加一個分行符號(\n)。否則會看到如下錯誤資訊:   // Error: line 1: OBJ file line 5: index out of range. //   // Error: line 1: Error reading file. //   在Maya中匯入"myObj.obj"檔案,會看到四邊形。這個四邊形的形狀是完全由前面的那5行代碼決定的。 

   我們來分析一下這些代碼。

   v -0.58 0.84 0 畫一個四邊形需要四個頂點,這是第一個頂點,"v"表示頂點(vertex),"-0.58"為這個頂點的X軸座標值,"0.84"為Y軸座標值,"0"為Z軸座標值。它的索引號是1。索引號是畫面時要用到的。   v 2.68 1.17 0  v 2.84 -2.03 0  v -1.92 -2.89 0 這分別是第二、三、四個頂點,它們的索引號分別是2,3,4。

   f 1 2 3 4   現在開始畫面,"f"表示面(face),1,2,3,4是前面那四個頂點的索引號。請注意畫這個面連接點的順序,是從第一個點出發,依次串連第二、三、四個點。如果串連的順序不同所產生的面也會截然不同,例如"f 1 2 4 3"會產生一個交迭的面。

   面的連接點是按順時針排列或逆時針排列,將決定面的法線方向(面的反正)。例如:"f 1 2 3 4"面的法線向外,"f 4 3 2 1"面的法線向裡。 面的連接點順序錯誤,是導致匯入模型產生碎面的一個重要原因。一個面不能出現兩個以上相同的頂點,這也是檢查OBJ檔案出錯的一個要點。例如:"f 1 2 3 4 3",有兩個相同的頂點,索引號是3。一個面出現兩個相同頂點,可能造成程式的記憶體配置錯誤。   下面來研究一下Maya匯出的OBJ檔案。   在Maya中建立一個多邊形立方體,選中這個立方體,選擇菜單"File -> Export Selection..."匯出格式為OBJ,檔案名稱為"cube.obj",如果沒有此格式,請在Plug-in Manager中載入"objExport.mll"。 用寫字板開啟"cube.obj",可以看到如下代碼:

# The units used in this file are centimeters.g defaultv -0.500000 -0.500000 0.500000v 0.500000 -0.500000 0.500000v -0.500000 0.500000 0.500000v 0.500000 0.500000 0.500000v -0.500000 0.500000 -0.500000v 0.500000 0.500000 -0.500000v -0.500000 -0.500000 -0.500000v 0.500000 -0.500000 -0.500000vt 0.000000 0.000000vt 1.000000 0.000000vt 0.000000 1.000000vt 1.000000 1.000000vt 0.000000 2.000000vt 1.000000 2.000000vt 0.000000 3.000000vt 1.000000 3.000000vt 0.000000 4.000000vt 1.000000 4.000000vt 2.000000 0.000000vt 2.000000 1.000000vt -1.000000 0.000000vt -1.000000 1.000000vn 0.000000 0.000000 1.000000vn 0.000000 0.000000 1.000000vn 0.000000 0.000000 1.000000vn 0.000000 0.000000 1.000000vn 0.000000 1.000000 0.000000vn 0.000000 1.000000 0.000000vn 0.000000 1.000000 0.000000vn 0.000000 1.000000 0.000000vn 0.000000 0.000000 -1.000000vn 0.000000 0.000000 -1.000000vn 0.000000 0.000000 -1.000000vn 0.000000 0.000000 -1.000000vn 0.000000 -1.000000 0.000000vn 0.000000 -1.000000 0.000000vn 0.000000 -1.000000 0.000000vn 0.000000 -1.000000 0.000000vn 1.000000 0.000000 0.000000vn 1.000000 0.000000 0.000000vn 1.000000 0.000000 0.000000vn 1.000000 0.000000 0.000000vn -1.000000 0.000000 0.000000vn -1.000000 0.000000 0.000000vn -1.000000 0.000000 0.000000vn -1.000000 0.000000 0.000000s offg pCube1usemtl initialShadingGroupf 1/1/1 2/2/2 4/4/3 3/3/4f 3/3/5 4/4/6 6/6/7 5/5/8f 5/5/9 6/6/10 8/8/11 7/7/12f 7/7/13 8/8/14 2/10/15 1/9/16f 2/2/17 8/11/18 6/12/19 4/4/20f 7/13/21 1/1/22 3/3/23 5/14/24
   這個檔案看起來稍複雜一些,用到了許多關鍵詞,你可以對照前面的列表查看一下每個關鍵詞的意思。我來解釋一下:
   "vt 1.000000 0.000000"這句"vt"代表點的貼圖座標。
   "vn 0.000000 0.000000 -1.000000"這句"vn"代表點的法線。
   "s off"表示關閉光滑組。
   "usemtl initialShadingGroup"表示使用的材質。
   "f 7/13/21"這時在面的資料中多了貼圖座標uv點和法線的索引號,索引號分別用斜線符號(/)隔開。
   格式:"f 頂點索引/uv點索引/法線索引"。
   "g pCube1"表示組,這裡的成組與Maya中的成組不一樣,這裡的成組是指把"g pCube1"後出現的面都結合到一起,組成一個整的多邊形幾何體。

   把"cube.obj"檔案修改一下就知道成組的意思了。把"s off"這句後面的代碼替換成以下代碼:
usemtl initialShadingGroupg pCube_Face1f 1/1/1 2/2/2 4/4/3 3/3/4g pCube_Face2f 3/3/5 4/4/6 6/6/7 5/5/8g pCube_Face3f 5/5/9 6/6/10 8/8/11 7/7/12g pCube_Face4f 7/7/13 8/8/14 2/10/15 1/9/16g pCube_Face5f 2/2/17 8/11/18 6/12/19 4/4/20g pCube_Face6f 7/13/21 1/1/22 3/3/23 5/14/24
    匯入Maya後可以看到,立方體的每個面是分離的,每個面的名稱分別是"pCube_Face(1~6)",可見組的名稱其實就是單獨幾何體的名稱。

    可不可以用中文命名幾何體(組)呢。試試就知道了,把前面的代碼改成:
usemtl initialShadingGroupg 立方體面1f 1/1/1 2/2/2 4/4/3 3/3/4g 立方體面2f 3/3/5 4/4/6 6/6/7 5/5/8g 立方體面3f 5/5/9 6/6/10 8/8/11 7/7/12g 立方體面4f 7/7/13 8/8/14 2/10/15 1/9/16g 立方體面5f 2/2/17 8/11/18 6/12/19 4/4/20g 立方體面6f 7/13/21 1/1/22 3/3/23 5/14/24
    試一下,會發現模型順利的匯入了。雖然物體的名稱都變亂碼了,可這並不是很嚴重的事。不過使用中文名並不總是這麼順利,把"g 立方體面1"這行改為"g 選擇"再試試看,這回匯入時模型根本無法出現,只會出現如下的錯誤資訊:
    // Error: line 1: Your OBJ file contains a line which is too long to be parsed. Please edit your obj file. //
    // Error: line 1: Error reading file. //
    由此可見,物體命名的不規範也是導致OBJ檔案出錯的原因之一。
    關於Maya的物體命名,英文名是很保險的,標點符號中只有底線(_)可用,數字不能用放到名稱的開頭,盡量不要用中、日、韓等雙位元組文字。

    OBJ檔案不支援有孔的多邊形面。舉個例子說明一下:選擇Maya的建立多邊形工具(Polygons -> Create Polyon Tool),在視圖中畫一個四邊形,不要按斷行符號,按Ctrl在四邊形中間點一下,可以繼續在四邊形中挖一個洞。把這個有孔的多邊形存成OBJ格式,在匯入Maya時,會發現多邊形少了一塊。如果你把這也看成錯誤,現在至少你已經知道錯誤的原因了,就是OBJ檔案不支援有孔的多邊形面。

4、OBJ檔案的實際問題:

    現在來討論一點比較實際的問題吧,就是一旦你遇到了一個出錯的OBJ檔案,倒底該怎麼辦。

    當你開啟OBJ檔案後,往往會看到有幾萬行的代碼,你恐怕還沒本事情一眼看出錯誤所在行,除非程式的錯誤資訊中已經告訴你錯誤行。如果你不知道錯誤在哪裡,可以用排除法,弄清楚肯定正確的代碼範圍,通過縮減錯誤碼範圍定位錯誤。例如,你先建立一個空的OBJ檔案,把有錯的OBJ檔案代碼粘貼一半過來,然後把這個只有一半代碼的新OBJ檔案匯入Maya。如果這時沒有錯誤資訊,說明錯誤行是在另一半代碼中,可以從另一半代碼中再粘貼一部分代碼試試看;如果這時出現錯誤,說明錯誤行就在粘貼的代碼中,可以把粘貼過來的代碼刪去一部分再試試看。就這樣,逐步縮減範圍直到找到錯誤行為止。
    這種方法雖然很麻煩,不過頗為有效。如果你不會編程,又遇到非常緊急的情況,這種方法還是值得一試的。


5、OBJ檔案的更多細節:

簡單的OBJ格式寫法。

# Simple Wavefront filev 0.0 0.0 0.0v 0.0 1.0 0.0v 1.0 0.0 0.0f 1 2 3
 面可以使用負值索引,有時用負值索引描述面更為簡便。 
v -0.500000 0.000000 0.400000v -0.500000 0.000000 -0.800000v -0.500000 1.000000 -0.800000v -0.500000 1.000000 0.400000f -4 -3 -2 -1
 "f -4 -3 -2 -1"這句索引值"-3"表示從"f"這行往上數第3個頂點,就是"v -0.500000 0.000000 -0.800000",其它的索引值以此類推。 因此與這一行等效的正值索引寫法為:"f 1 2 3 4"    OBJ檔案不包含面的顏色定義資訊,不過可以引用材質庫,材質庫資訊儲存在一個尾碼是".mtl"的獨立檔案中。關鍵字"mtllib"即材質庫的意思。材質庫中包含材質的漫射(diffuse),環境(ambient),光澤(specular)的RGB(紅綠藍)的定義值,以及反射(specularity),折射(refraction),透明度(transparency)等其它特徵。"usemtl"指定了材質之後,以後的面都是使用這一材質,直到遇到下一個"usemtl"來指定新的材質。 

指定材質的方法:

Cube with Materials:# This cube has a different material# applied to each of its faces.mtllib master.mtlv 0.000000 2.000000 2.000000v 0.000000 0.000000 2.000000v 2.000000 0.000000 2.000000v 2.000000 2.000000 2.000000v 0.000000 2.000000 0.000000v 0.000000 0.000000 0.000000v 2.000000 0.000000 0.000000v 2.000000 2.000000 0.000000# 8 verticesg frontusemtl redf 1 2 3 4g backusemtl bluef 8 7 6 5g rightusemtl greenf 4 3 7 8g topusemtl goldf 5 1 4 8g leftusemtl orangef 5 6 2 1g bottomusemtl purplef 2 6 7 3# 6 elements

貝塞爾片面(Bezier Patch):
Maya不能匯出OBJ格式的貝塞爾片面,卻能夠匯入它。匯入的貝塞爾片面自動轉換為Nurbs表面。

# 3.0 Bezier patchv -5.000000 -5.000000 0.000000v -5.000000 -1.666667 0.000000v -5.000000 1.666667 0.000000v -5.000000 5.000000 0.000000v -1.666667 -5.000000 0.000000v -1.666667 -1.666667 0.000000v -1.666667 1.666667 0.000000v -1.666667 5.000000 0.000000v 1.666667 -5.000000 0.000000v 1.666667 -1.666667 0.000000v 1.666667 1.666667 0.000000v 1.666667 5.000000 0.000000v 5.000000 -5.000000 0.000000v 5.000000 -1.666667 0.000000v 5.000000 1.666667 0.000000v 5.000000 5.000000 0.000000# 16 verticescstype bezierdeg 3 3# Example of line continuationsurf 0.000000 1.000000 0.000000 1.000000 13 14 \15 16 9 10 11 12 5 6 7 8 1 2 3 4parm u 0.000000 1.000000parm v 0.000000 1.000000end  # 1 element


基數曲線(Cardinal Curve):

Maya好像不支援OBJ格式的曲線,匯入時不會出現錯誤資訊,卻也不會出現曲線。

# 3.0 Cardinal curvev 0.940000 1.340000 0.000000v -0.670000 0.820000 0.000000v -0.770000 -0.940000 0.000000v 1.030000 -1.350000 0.000000v 3.070000 -1.310000 0.000000# 6 verticescstype cardinaldeg 3curv 0.000000 3.000000 1 2 3 4 5 6parm u 0.000000 1.000000 2.000000 3.000000 end# 1 element

貼圖映射(Texture-Mapped):

# A 2 x 2 square mapped with a 1 x 1 square# texture stretched to fit the square exactly.mtllib master.mtlv 0.000000 2.000000 0.000000v 0.000000 0.000000 0.000000v 2.000000 0.000000 0.000000v 2.000000 2.000000 0.000000vt 0.000000 1.000000 0.000000vt 0.000000 0.000000 0.000000vt 1.000000 0.000000 0.000000vt 1.000000 1.000000 0.000000# 4 verticesusemtl wood# The first number is the point,# then the slash,# and the second is the texture pointf 1/1 2/2 3/3 4/4# 1 element



轉載自:http://www.cppblog.com/lovedday/archive/2008/06/13/53153.html


————The End————

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.