討論區快速選單
知識庫快速選單
網路投保旅行平安險 網路投保旅行平安險
[ 回上頁 ] [ 討論區發言規則 ]
[心得] AutoCAD檔案格式 (含2004)
更改我的閱讀文章字型大小
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:20:03
目前2004版AutoCAD dwg檔案格式的相關文件, 網路上是完全找不到, 除了OpenDWG之外. 不過OpenDWG要加入它的會員才能download到檔案格式文件, 而且該文件的內容除了寫得很模糊, 常常漏掉重要的東西之外, 解壓演算法也是錯誤百出. 我不知是OpenDWG故意的, 還是忘了更新, 反正我在解2004版dwg檔時, 雖然也參考OpenDWG的文件, 但確實也花了不少工夫去補足沒提的事項, 並修正裡面的錯誤. 這些遺漏與錯誤之處, 我已e-mail通知OpenDWG, 但不知會不會update到它的文件...

由於我的目的只是解出裡面的文字內容, 因此其他與這個目的無關的資訊, 我都會略掉不提. 因此如果你想知道更詳細的格式內容, 那麼便去跟OpenDWG申請成會員, 再download他們的文件 (我會建議先看我的文件, 再看他們的, 會比較容易弄懂).

底下這篇文件是我解dwg檔的心得文件, 由於前後都會相互參考, 因此必須從舊版的格式開始談起, 否則單po 2004版的會不容易看懂.
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:21:47
一. AutoCAD DWG檔R13/R14版

AutoCAD DWG檔各種版本的檔案格式都不太一樣,由於R13/R14版最常見,公開資料也最多,因此我們首先以這個版本開始說明起。R13/R14版DWG檔的檔頭如下:

a. (00h)標記:2 byte,固定”AC”
b. (02h)版本:4 byte數字字串,1002為2.5V,1003為2.6V,1004為R9,1006為R10,1009為R12,1012為R13,1014為R14,1015為2000,1018為2004
c. (06h)保留:7 byte
d. (0Dh)影像資料位置:4 byte long
e. (11h)保留:2 byte
f. (13h)CodePage:2 byte
g. (15h)節區指標記錄數目:long
h. (19h)節區指標記錄:每個9 byte,格式為記錄編號1 byte,檔案位置4 byte,大小4 byte(後述)
i. (??h)CRC:2 byte
j. (??h)結束標記:16 byte,固定為0x95, 0xA0, 0x4E, 0x28, 0x99, 0x82, 0x1A, 0xE5, 0x5E, 0x41, 0xE0, 0x5F, 0x9D, 0x3A, 0x4D, 0x00

以下為節區指標記錄編號的意義:

0 = 指向檔頭變數區
1 = 指向Class定義區
2 = 指向物件對應區
3 = 指向特殊表格區(R13C3版以後才有,R13版本若有此記錄為R13C3版,否則為R13C2版)
4 = 指向額外資料記錄區(R14版以後才有)
5 = 指向額外檔頭區

由於我們需要抽出的文字資料是由物件對應區所指向,因此必須先弄懂物件對應區的格式。但由於物件形態值會受Class定義區影響,故一開始必須先讀取Class定義區。Class定義區的格式如下:

a. 開始標記:16 byte,固定為0x8D, 0xA1, 0xC4, 0xB8, 0xC4, 0xA9, 0xF8, 0xC5, 0xC0, 0xDC, 0xF4, 0x5F, 0xE7, 0xCF, 0xB6, 0x8A
b. 節區大小:long,不含本資料、標記與CRC
c. Class定義資料
d. CRC:2 byte
e. 結束標記:16 byte,固定為0x72, 0x5E, 0x3B, 0x47, 0x3B, 0x56, 0x07, 0x3A, 0x3F, 0x23, 0x0B, 0xA0, 0x18, 0x30, 0x49, 0x75

Class定義資料格式如下(注意是以bit為單位,而非以byte為單位):

a. 物件形態值:bitshort(>=500)
b. 權限值:bitshort
c. Appname:長度(bitshort)+字串
d. C++name:長度(bitshort)+字串
e. dxfname:長度(bitshort)+字串,對應的DXF物件名稱
f. zombie:1 bit
g. Class id:bitshort

其中比較重要的是物件形態值與dxfname,用來表示物件資料區裡的物件形態對應的資料格式,這點後面再來說明。由於這邊用了一些AutoCAD自定的資料格式,故我們先說明一下各種會用到的特殊資料格式:

1. bitshort

先讀取2個位元做判斷如下:

a. 00:後面接2 byte做為short值(低位元組在前)
b. 01:後面接1 byte做為short值(正整數)
c. 10:0
d. 11:256

2. bitlong

先讀取2個位元做判斷如下:

a. 00:後面接4 byte做為long值(低位元組在前)
b. 01:後面接1 byte做為long值(正整數)
c. 10:0
d. 11:未使用

3. bitdouble

先讀取2個位元做判斷如下:

a. 00:後面接double值
b. 01:1.0
c. 10:0.0
d. 11:未使用

4. handle參用格式

a. code:4 bit
b. handle位元組數目:4 bit
c. handle位元組資料

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:22:48
物件對應區裡是由一堆節區所組成,並以一個空節區(大小=2)做為結束。各節區的格式如下:

a. 節區大小:2 byte,最高位元組在前(含CRC但不含節區大小資料)
b. 節區資料:以handle offset與position offset成對組成,亦即讀出的值要與前項值相加
c. CRC:2 byte

其中我們要的只有物件的檔案位置(position)而已。必須注意的是,節區資料中的handle offset與position offset是有壓縮的(Modular Char),解法如下:

a. 讀取一個位元組,若最高位元=1,表示後面還有資料,將低7位元做為實際資料低位元部份,重複這個步驟,直到最高低元=0為止
b. 最後一個位元組第二高低元表示正負號,其餘6位元為資料

得到各物件位置後,接下來便是要解出各物件的資料,各物件資料的格式如下:

a. 物件大小:Modular Short(不含CRC與物件大小資料)
b. 物件資料
c. CRC:2 byte

Modular Short格式和Modular Char格式類似,只不過單位由位元組改成短整數(short)而已,但最後一個短整數第二高低元為資料,不代表正負號(最多應兩個短整數)。至於物件資料的格式如下(注意物件資料是以bit為單位,而非以byte為單位):

a. 物件形態:bitshort
b. 物件handle:handle參用格式
c. 額外資料(EED,後述)
d. 實際物件資料
e. 相關物件handle:handle參用格式

額外資料(EED)裡雖然也有文字,但都是內部的變數名稱,故直接將之略過即可。其格式如下:

EED大小:bitshort,單位為byte
EED資料

注意上述資料可能有多組,必須持續讀到EED大小為0時才結束。以下便是我們應處理物件的實際物件資料格式:

1. Text(形態值=1)
2. Attribute(形態值=2)
3. Attribute Define(形態值=3)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. 物件大小:long,單位為位元
d. Entity Mode:2 bit
e. Reactor數目:bitlong
f. Bylayer旗標:1 bit
g. NoLink旗標:1 bit
h. 顏色:bitshort
i. Ltype Scale:bitdouble
j. Invisibility:bitshort
k. Elevation:bitdouble
l. Insertion pt:2個double
m. Alignment pt:2個double
n. Extrusion:3個bitdouble
o. Thickness:bitdouble
p. Oblique Angle:bitdouble
q. Rotation Angle:bitdouble
r. Height:bitdouble
s. Width Factor:bitdouble
t. 文字:長度(bitshort)+字串
u. (…以下略…)

4. Ordinate Dimension(形態值=20)
5. Linear Dimension(形態值=21)
6. Aligned Dimension(形態值=22)
7. Angular 3PT Dimension(形態值=23)
8. Angular 2Line Dimension(形態值=24)
9. Radius Dimension(形態值=25)
10. Diameter Dimension(形態值=26)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. 物件大小:long,單位為位元
d. Entity Mode:2 bit
e. Reactor數目:bitlong
f. Bylayer旗標:1 bit
g. NoLink旗標:1 bit
h. 顏色:bitshort
i. Ltype Scale:bitdouble
j. Invisibility:bitshort
k. Extrusion:3個bitdouble
l. Text midpt:2個double
m. Elevation:bitdouble
n. Flag:1 byte
o. 文字:長度(bitshort)+字串
p. (…以下略…)

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:23:32
11. MText(形態值=44)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. 物件大小:long,單位為位元
d. Entity Mode:2 bit
e. Reactor數目:bitlong
f. Bylayer旗標:1 bit
g. NoLink旗標:1 bit
h. 顏色:bitshort
i. Ltype Scale:bitdouble
j. Invisibility:bitshort
k. Insertion pt:3個bitdouble
l. Extrusion:3個bitdouble
m. X-axis dir:3個bitdouble
n. Rect width:bitdouble
o. Text height:bitdouble
p. Attachment:bitshort
q. Drawing dir:bitshort
r. Extents ht:bitdouble
s. Extents wid:bitdouble
t. 文字:長度(bitshort)+字串
u. (…以下略…)

12. Tolerance(形態值=46)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. 物件大小:long,單位為位元
d. Entity Mode:2 bit
e. Reactor數目:bitlong
f. Bylayer旗標:1 bit
g. NoLink旗標:1 bit
h. 顏色:bitshort
i. Ltype Scale:bitdouble
j. Invisibility:bitshort
k. Unknown:bitshort
l. Height:bitdouble
m. Dimgap:bitdouble
n. Insertion pt:3個bitdouble
o. X-axis dir:3個bitdouble
p. Extrusion:3個bitdouble
q. 文字:長度(bitshort)+字串
r. (…以下略…)

13. LType(形態值=57)

a. 物件大小:long,單位為位元
b. Reactor數目:bitlong
c. Entry name:長度(bitshort)+字串
d. 64旗標:1 bit
e. xrefindex:bitshort
f. xdep:1 bit
g. Description:長度(bitshort)+字串
h. Pattern len:bitdouble
i. Alignment:1 byte
j. Dash數目:1 byte
k. Dash資料:筆數為Dash數目
l. 文字資料區:256 byte
m. (…以下略…)

Dash資料格式為:

a. Dash長度:bitdouble
b. Shapecode:bitshort
c. Xoffset:double
d. Yoffset:double
e. Scale:bitdouble
f. Rotation:bitdouble
g. Shapeflag:bitshort

當Shapeflag最低第2個位元(mask=0x02)為1時,表示該Dash為文字,實際文字在文字資料區中(ASCIIZ格式),位置由Shapecode決定。

14. ArcAlignedText(形態值依Class定義區而定)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. 物件大小:long,單位為位元
d. Entity Mode:2 bit
e. Reactor數目:bitlong
f. Bylayer旗標:1 bit
g. NoLink旗標:1 bit
h. 顏色:bitshort
i. Ltype Scale:bitdouble
j. Invisibility:bitshort
k. Unknown:6個文字字串
l. 文字:長度(bitshort)+字串
m. (…以下略…)

繪圖資料的格式如下:

a. 資料總長度:long,單位為byte
b. 實際繪圖資料

實際繪圖資料由多個繪圖物件所組成,其格式如下:

c. 繪圖物件長度:long,單位為byte
d. 繪圖物件形態:long
e. 繪圖物件資料

注意繪圖物件資料必須是4 byte alignment。繪圖資料中可有文字資料,但暫無相關檔案可測,故目前均先加以略過不處理。

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:23:52
注意AutoCAD的文字可能以{}括起來,表示更換段落。另外,文字內也可以使用命令做控制,以下是一些常見命令:

a. \A:是否對齊,以;做結束
b. \C:更換顏色,以;做結束
c. \F:更換字型,以;做結束
d. \H:不明,以;做結束
e. \P:更換段落
f. \U:Unicode字元,後接+,再接4個hex字元
g. \f:更換字型,以;做結束
h. \pt:變更字型大小,以;做結束
i. %%:特殊字元,後接一個字母(%%d為度的標記)

由於AutoCAD裡的字串都是ANSI格式,如果要轉成Unicode,必須依照CodePage資訊來進行轉碼,以下便是AutoCAD裡的CodePage資訊所對應的語系:

00:undefined
01:ASCII
02:iso 8859-1
03:iso 8859-2
04:iso 8859-3
05:iso 8859-4
06:iso 8859-5
07:iso 8859-6
08:iso 8859-7
09:iso 8859-8
10:iso 8859-9
11:dos 437
12:dos 850
13:dos 852
14:dos 855
15:dos 857
16:dos 860
17:dos 861
18:dos 863
19:dos 864
20:dos 865
21:dos 869
22:dos 932
23:mac-roman
24:big5
25:ksc 5601
26:johab
27:dos 866
28:ansi 1250
29:ansi 1251
30:ansi 1252
31:gb 2312
32:ansi 1253
33:ansi 1254
34:ansi 1255
35:ansi 1256
36:ansi 1257
37:ansi 874
38:ansi 932
39:ansi 936
40:ansi 949
41:ansi 950
42:ansi 1361
43:ansi 1200

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:24:58
二. AutoCAD DWG檔2000版

AutoCAD DWG檔2000版的格式,主要在於物件格式的變動,其餘像檔頭、Class定義區、物件對應區的格式仍與R13/R14版相同。新的物件資料格式如下:

a. 物件形態:bitshort
b. 物件大小:long,單位為bit
c. 物件handle:handle參用格式
d. 額外資料(EED,後述)
e. 實際物件資料
f. 相關物件handle:handle參用格式

主要的差異在於物件大小從實際物件資料中調到最前面的地方。實際物件資料的格式也大不相同,以下便是應處理物件的格式:

1. Text(形態值=1)
2. Attribute(形態值=2)
3. Attribute Define(形態值=3)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. Entity Mode:2 bit
d. Reactor數目:bitlong
e. NoLink旗標:1 bit
f. 顏色:bitshort
g. Ltype Scale:bitdouble
h. Flags:4 bit
i. Invisibility:bitshort
j. LineWeight:1 byte
k. DataFlag:8 bit
l. Elevation:double,必須當DataFlag bit 0(mask=0x01)=0時才有
m. Insertion pt:2個double
n. Alignment pt:2個bitdoubledef,,必須當DataFlag bit 1(mask=0x02)=0時才有
o. Extrusion:bitextrusion
p. Thickness:bitthickness
q. Oblique Angle:double,必須當DataFlag bit 2(mask=0x04)=0時才有
r. Rotation Angle:double,必須當DataFlag bit 3(mask=0x08)=0時才有
s. Height:double
t. Width Factor:double,必須當DataFlag bit 4(mask=0x10)=0時才有
u. 文字:長度(bitshort)+字串
v. (…以下略…)

4. Ordinate Dimension(形態值=20)
5. Linear Dimension(形態值=21)
6. Aligned Dimension(形態值=22)
7. Angular 3PT Dimension(形態值=23)
8. Angular 2Line Dimension(形態值=24)
9. Radius Dimension(形態值=25)
10. Diameter Dimension(形態值=26)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. Entity Mode:2 bit
d. Reactor數目:bitlong
e. NoLink旗標:1 bit
f. 顏色:bitshort
g. Ltype Scale:bitdouble
h. Flags:4 bit
i. Invisibility:bitshort
j. LineWeight:1 byte
k. Extrusion:3個bitdouble
l. Text midpt:2個double
m. Elevation:bitdouble
n. Flag:1 byte
o. 文字:長度(bitshort)+字串
p. (…以下略…)

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:25:47
11. MText(形態值=44)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. Entity Mode:2 bit
d. Reactor數目:bitlong
e. NoLink旗標:1 bit
f. 顏色:bitshort
g. Ltype Scale:bitdouble
h. Flags:4 bit
i. Invisibility:bitshort
j. LineWeight:1 byte
k. Insertion pt:3個bitdouble
l. Extrusion:3個bitdouble
m. X-axis dir:3個bitdouble
n. Rect width:bitdouble
o. Text height:bitdouble
p. Attachment:bitshort
q. Drawing dir:bitshort
r. Extents ht:bitdouble
s. Extents wid:bitdouble
t. 文字:長度(bitshort)+字串,參見R13/R14版之說明
u. (…以下略…)

12. Tolerance(形態值=46)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. Entity Mode:2 bit
d. Reactor數目:bitlong
e. NoLink旗標:1 bit
f. 顏色:bitshort
g. Ltype Scale:bitdouble
h. Flags:4 bit
i. Invisibility:bitshort
j. LineWeight:1 byte
k. Insertion pt:3個bitdouble
l. X-axis dir:3個bitdouble
m. Extrusion:3個bitdouble
n. 文字:長度(bitshort)+字串
o. (…以下略…)

13. LType(形態值=57)

a. Reactor數目:bitlong
b. Entry name:長度(bitshort)+字串
c. 64旗標:1 bit
d. xrefindex:bitshort
e. xdep:1 bit
f. Description:長度(bitshort)+字串
g. Pattern len:bitdouble
h. Alignment:1 byte
i. Dash數目:1 byte
j. Dash資料:筆數為Dash數目,請參閱R13/R14版格式說明
k. 文字資料區:256 byte
l. (…以下略…)

14. ArcAlignedText(形態值依Class定義區而定)

a. 繪圖旗標:1 bit
b. 繪圖資料:當繪圖旗標=1時才有(後述)
c. Entity Mode:2 bit
d. Reactor數目:bitlong
e. NoLink旗標:1 bit
f. 顏色:bitshort
g. Ltype Scale:bitdouble
h. Flags:4 bit
i. Invisibility:bitshort
j. LineWeight:1 byte
k. Unknown:6個文字字串
l. 文字:長度(bitshort)+字串
m. (…以下略…)

以下則為2000版新增的特殊資料格式:

1. bitdoubledef

先讀取2個位元做判斷如下:

a. 00:使用內定值
b. 01:4 byte double
c. 10:6 byte double
d. 11:8 byte double

2. bitextrusion

先讀取1個位元,若為1則使用內定值,否則便讀取3個bitdouble

3. bitthickness

先讀取1個位元,若為1則使用內定值,否則便讀取3個bitdouble

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:26:12
三. AutoCAD DWG檔R9/R10/R12版

R9/R10/R12版均以byte為單位儲存,因此比R13以後的版本容易處理,其檔頭如下:

a. (00h)版本標記:12 byte,參見R13/R14版說明
b. (0Ch)不明:8 byte
c. (14h)Entity起始位置:long
d. (18h)Entity結束位置:long
e. (1Ch)Block起始位置:long
f. (20h)不明:4 byte
g. (24h)Block結束位置:long

資料主要放在Entity和Block這兩區內,注意結束位置若為0,表示檔尾。另外,CodePage資訊係放在0x3F9處,佔2 byte。

Entity和Block裡的資料由Entity所組成,每個Entity開頭資訊為:

a. 形態:1 byte
b. 旗標(flag):1 byte
c. 大小:2 byte,含4 byte開頭資訊

Entity開頭資訊後為Entity基礎資訊,內容為:

a. layer:2 byte
b. 選項(opts):2 byte
c. color:1 byte,flag & 1且R12之後版本才有
d. 額外旗標(extra):1 byte,flag & 0x40時才有
e. 額外資料:前2 byte為大小,其後接資料,extra & 2時才有
f. 不明:2 byte,flag & 2時才有
g. z座標:8 byte double,flag & 4且形態值>2(22除外)時才有
h. 寬度:8 byte double,flag & 8時才有
i. handle:第1 byte為大小,其後接資料,flag & 0x20時才有
j. 紙張編號:2 byte,extra & 4時才有

Entity基礎資訊後面接著各Entity的個別資料,目前我們只需處理文字Entity,其形態值為7,其個別資料格式為:

a. 位置:2個8 byte double
b. 不明:8 byte double
c. 字串:前2 byte為大小,其後接字串資料(不含NULL結束字元)

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:27:30
四. AutoCAD DWG檔2004版

2004版開始,AutoCAD DWG檔加入了很多的加密與壓縮,因此解起來非常麻煩。其主檔頭如下:

a. (00h)版本標記:12 byte,參見R13/R14版說明
b. (0Ch)不明:1 byte
c. (0Dh)Preview Address:4 byte long
d. (11h)DWG Version:1 byte
e. (12h)Main Release Version:1 byte
f. (13h)Code Page:2 byte short
g. (15h)不明:3 byte
h. (18h)Security Type:4 byte long
i. (1Ch)不明:4 byte
j. (20h)DWG Property Addr:4 byte long
k. (24h)VBA Project Addr:4 byte long
l. (28h)不明:4 byte
m. (2Ch)保留:84 byte(54h),固定為0
n. (80h)額外主檔頭:108 byte(6Ch),有加密

其中額外主檔頭的解密法如下(假設p指向加密的額外主檔頭):

long randseed = 1;
for (i=0; i<108; i++)
{
randseed *= 0x343fd;
randseed += 0x269ec3;
p[i] ^= randseed >> 16;
}

解密後,額外主檔頭的資訊如下:

a. (00h)檔頭標記字串:12 byte,固定為”AcFssFcAJMB”
b. (0Ch)不明:12 byte
c. (18h)Root Tree Node Gap:4 byte long
d. (1Ch)Lowermost Left Tree Node Gap:4 byte long
e. (20h)Lowermost Right Tree Node Gap:4 byte long
f. (24h)不明:4 byte
g. (28h)Last Section ID:4 byte long
h. (2Ch)Last Section Addr:4 byte long
i. (30h)保留:4 byte,固定為0
j. (34h)Second Header Addr:4 byte long
k. (38h)保留:4 byte,固定為0
l. (3Ch)Gap Amount:4 byte long
m. (40h)Section Amount:4 byte long
n. (44h)不明:12 byte
o. (50h)Section Map ID:4 byte long
p. (54h)Section Map Addr:4 byte long(需加100h才是實際位置)
q. (58h)保留:4 byte,固定為0
r. (5Ch)Section Info ID:4 byte long
s. (60h)Section Array Size:4 byte long
t. (64h)Gap Array Size:4 byte long
u. (68h)CRC:4 byte long

接下來的資料由許多的Section所組成,各Section的位置與大小由Section Map資訊決定。Section Map資訊的位置,在額外主檔頭裡記錄的Section Map Addr + 100h的地方,它是由許多小節區所組成,各小節區的格式為:

a. Section Mark:4 byte long,固定為0x41630e3b
b. 解壓後資料大小:4 byte long
c. 解壓前資料大小:4 byte long
d. 壓縮方法:4 byte long,1表無壓縮,2表有壓縮
e. 檢查碼:4 byte long
f. 壓縮過的Section Map資料

以上必須不斷的重複解開壓縮過的Section Map資料並合併在一起,直到遇到資料大小為0的小節區為止。解壓縮的方式我們最後再來說明。解開後的Section Map資料格式如下:

a. Section ID:4 byte long
b. Section Size:4 byte long

其中Section ID係由小排到大(不一定連續),同時當Section ID若為負值時,表示該Section的資料是無用的(Section與Section間的Gap),同時其後會再接著下列資訊:

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:28:15
a. Parent Node Gap:4 byte long
b. Left Node Gap:4 byte long
c. Right Node Gap:4 byte long
d. 保留:固定為0

由於第一個Section的位置固定在100h的地方,因此藉由Section的ID與大小,我們便可以得知各Section的位置。注意在額外主檔頭的Section Map ID與Section Info ID,由於這兩種資訊都各佔用一個Section,而格式與標準的Section有點不同,因此必須在Section Map資訊裡特別加以辨識處理。

Section Map資訊的目的,主要是找出各Section的位置。然而單只找出Section位置是不夠的,我們還必須經由Section Info裡的資訊,才能找出諸如Header Variable、Object Map、Class Definition等資料串(Stream)所佔用的Section與次序。

Section Info資訊也是由許多小節區所組成,各小節區的格式為:

a. Section Mark:4 byte long,固定為0x4163003b
b. 解壓後資料大小:4 byte long
c. 解壓前資料大小:4 byte long
d. 壓縮方法:4 byte long,1表無壓縮,2表有壓縮
e. 檢查碼:4 byte long
f. 壓縮過的Section Info資料

以上必須不斷的重複解開壓縮過的Section Info資料並合併在一起,直到遇到資料大小為0的小節區為止。解開後的Section Info資料格式如下:

a. Section Description數目:4 byte long
b. 不明:16 byte
c. Section Description資料,數目由前面決定

Section Description資料的格式如下:

a. 資料串的總大小:4 byte long
b. 不明:4 byte
c. 本資料串使用的Section數:4 byte long
d. Section資料解壓後的最大資料數:4 byte long
e. 不明:4 byte
f. 壓縮方法:4 byte long,1表無壓縮,2表有壓縮
g. 資料串形態值(Section Type):4 byte long
h. 是否加密:4 byte long
i. 資料串形態名稱:64 byte ASCIIZ字串
j. 使用的Section資訊:數目由前面決定

各資料串使用的Section資訊格式如下:

a. Section ID:4 byte long
b. Section資料解壓前的大小:4 byte long
c. Section資料解壓後應放在資料串的位置:4 byte long
d. 不明:4 byte

注意資料串形態值並沒有固定,因此必須由資料串形態名稱來決定。以下為目前已知的資料串形態名稱:

AcDb:Header(同R13/R14的Header Variable節區內容)
AcDb:AuxHeader(同R13/R14的額外檔頭節區內容)
AcDb:Classes(同R13/R14的Class Definition節區內容)
AcDb:Handles(同R13/R14的Object Map節區內容)
AcDb:Template
AcDb:ObjFreeSpace
AcDb:AcDbObjects(同R14/R14的物件資料)
AcDb:RevHistory
AcDb:FileDepList
AcDb:SummaryInfo
AcDb:Preview

因此處理的方法和R13/R14一樣,先解出Class Definition與Class Definition的資料串,得知各資料物件的起始位置,然後再解出AcDbObjects資料串,剖析每個資料物件,即可得到我們要的文字內容。不過在處理各資料串所佔的Section前,我們還要再說明一下這些Section的格式。它的格式和前面提的Section Map與Section Info不太一樣,每個Section都有32 byte的Header,格式如下:

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:28:56
a. Section Mark:4 byte long,固定為0x4163043b
b. Section內的資料大小:4 byte long
c. 整個Section大小:4 byte long(含Section Header)
d. Section資料解壓後在資料串的位置:4 byte long
e. 不明:4個4 byte long
f. 壓縮過的Section 資料

其中32 byte Section Header裡,每個長整數都有加密過,必須與下列的mask做互斥運算後,才能得回實際的值:

mask = 0x4164536b ^ Section起始位置

至於Section資料是否有壓縮,必須由Section Info裡的Section Description得知。以下為壓縮方法為2時的解壓方法(假設S為輸入資料,D為輸出資料):

取得Literal Length
for (;;)
{
讀取S共Literal Length個byte資料到D
unsigned char ch = 讀取S一個byte
if (ch <= 0x0F) 有問題…
else if (ch == 0x10)
{
Compressed Bytes = 取得Long Compression Bytes + 9
Compressed Offset, Literal Length = 取得2 Byte Offset
Compressed Offset += 0x3FFF
if (Literal Length == 0) 取得Literal Length
}
else if (ch == 0x11) break
else if (ch <= 0x17)
{
Compressed Bytes = (ch & 0x0F) + 2
Compressed Offset, Literal Length = 取得2 Byte Offset
Compressed Offset += 0x3FFF
if (Literal Length == 0) 取得Literal Length
}
else if (ch == 0x18)
{
Compressed Bytes = 取得Long Compression Bytes + 9
Compressed Offset, Literal Length = 取得2 Byte Offset
Compressed Offset += 0x7FFF
if (Literal Length == 0) 取得Literal Length
}
else if (ch <= 0x1F)
{
Compressed Bytes = (ch & 0x07) + 2
Compressed Offset, Literal Length = 取得2 Byte Offset
Compressed Offset += 0x7FFF
if (Literal Length == 0) 取得Literal Length
}
else if (ch == 0x20)
{
Compressed Bytes = 取得Long Compression Bytes + 33
Compressed Offset, Literal Length = 取得2 Byte Offset
if (Literal Length == 0) 取得Literal Length
}
else if (ch <= 0x3F)
{
Compressed Bytes = ch - 0x1E
Compressed Offset, Literal Length = 取得2 Byte Offset
if (Literal Length == 0) 取得Literal Length
}
else
{
Compressed Bytes = ((ch & 0xF0) >> 4) - 1
unsigned char ch2 = 讀取S一個byte
Compressed Offset = (ch2 << 2) | ((ch & 0x0C) >> 2)
Literal Length = ch & 0x03
if (Literal Length == 0) 取得Literal Length
}
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/9 下午 03:29:34
out_pos = D目前應寫入的位置
pre_pos = out_pos – Compressed Offset – 1
從D的pre_pos位置拷貝資料到out_pos位置,共計Compressed Bytes位元組
}

取得Literal Length:

unsigned char ch = 讀取S一個byte
if (ch == 0)
{
Literal Length = 0x0F+3
for (;;)
{
ch = 讀取S一個byte
if (ch != 0) break
Literal Length += 0xFF
}
Literal Length += ch
}
else if (ch <= 0x0F) Literal Length = ch + 3
else if (ch & 0xF0)
{
Literal Length = 0
將S往回一個位置(即未讀取時狀態)
}
else 有問題…

取得Long Compression Bytes:

Compressed Bytes = 0;
for (;;)
{
ch = 從S讀取一個byte
if (ch != 0) break;
Compressed Bytes += 0xFF
}
Compressed Bytes += ch;

取得2 Byte Offset:

ch1 =從S讀取一個byte
ch2 =從S讀取一個byte
Compressed Offset = (ch1 >> 2) | (ch2 << 6)
Literal Length = ch1 & 0x03;

至於物件資料格式改變如下:

1. LType(形態值=57)

a. Reactor數目:bitlong
b. Xdic Missing Flag:1 bit
c. Entry name:長度(bitshort)+字串
d. 64旗標:1 bit
e. xrefindex:bitshort
f. xdep:1 bit
g. Description:長度(bitshort)+字串
h. Pattern len:bitdouble
i. Alignment:1 byte
j. Dash數目:1 byte
k. Dash資料:筆數為Dash數目,請參閱R13/R14版格式說明
l. 文字資料區:256 byte
m. (…以下略…)

作者 : waterboy(waterboy)
[ 貼文 88 | 人氣 1328 | 評價 80 | 評價/貼文 0.91 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/21 下午 10:40:14
讚讚讚!感謝青衫前輩的分享,小弟是做圖控軟體的,
客戶很多都是做機械加工機台的業者,他們都很習慣用
AutoCAD繪圖,小弟一直設法在圖控軟體裡顯示.dwg,
不過卻苦於沒有檔案格式資料而無法實作,感謝前輩的分享............Orz
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/9/22 下午 03:30:05
>小弟一直設法在圖控軟體裡顯示.dwg,
>不過卻苦於沒有檔案格式資料而無法實作

如果要做dwg的顯示, 單就我po的這篇資訊是不太夠的, 請跟我連絡一下: cin@webgenie.com.tw
作者 : qaz123wsx(哈哈)
[ 貼文 1 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/8/22 下午 06:07:38
非常感谢,收益非浅
作者 : alvinken(慕少艾)
[ 貼文 56 | 人氣 896 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/10 上午 11:33:49
小弟最近正著手寫一個顯示.dwg 圖檔的程式

不過,光在讀取內碼時,儲存至變數就有些問題

順便請問一下,如要顯示.dwg 還需要哪些資訊

作者 : am86047(遇遇)
[ 貼文 9 | 人氣 250 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/11/24 下午 03:08:51
青衫大大:
     我工作現在需要解讀.DWG檔,並自行畫線。之前有去下載Opendwg的.H和.LIB,但只要使用他所提供的函式就是出現
     error LNK2001: unresolved external symbol _odior_fread ,這個錯誤
     請問一下是我下載的版本有問題嗎,還是有其他的解決方式,若有需要Opendwg的.H和.LIB可以轉寄給你,麻煩一下。
作者 : sieben(阿七)
[ 貼文 3 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2011/3/28 下午 08:40:27
楼主你好!
我是做AutoCAD二次开发的!
现在我想试试用二进制直接打开Dwg文件读取里面的数据!
我有Dwg的文件格式说明,不过是英文版的,对我来说是个困难!
通过搜索来到这里,中文的说明对我来说好很多(还没来得看)
若楼主有更多的相关资料可以提供的!敬请送赠一二,先谢!
(若能示意怎样获取到一个圆Circle的直径,那就更好了!)
本人E_Mail : Sieben@sina.com
作者 : sieben(阿七)
[ 貼文 3 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2011/3/28 下午 08:40:39
楼主你好!
我是做AutoCAD二次开发的!
现在我想试试用二进制直接打开Dwg文件读取里面的数据!
我有Dwg的文件格式说明,不过是英文版的,对我来说是个困难!
通过搜索来到这里,中文的说明对我来说好很多(还没来得看)
若楼主有更多的相关资料可以提供的!敬请送赠一二,先谢!
(若能示意怎样获取到一个圆Circle的直径,那就更好了!)
本人E_Mail : Sieben@sina.com
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2011/3/30 下午 05:04:16
二次開發啊... 最好直接找Autodesk授權吧. Autodesk目前極力維護AutoCAD檔不被破解, 像OpenDWG等專破AutoCAD檔案的機構組織都已經被告了, 可以想見, 未來恐怕很難再自行處理AutoCAD新版的格式了.

又, 英文資料要能習慣閱讀, 等別人中文化, 已經慢了一大截了.
作者 : sieben(阿七)
[ 貼文 3 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2011/4/1 上午 11:13:26
呵呵,所以我并不大喜欢利用DwgDirect,我想要么就直接读Dwg,要么就乖乖的使用Autodesk提供的API.
看了青衫你的说明,我再去看英文的,就容易明白多了!谢谢青衫!
期待青衫有更多的文字出来!
现在大陆有一大堆仿造AutoCAD的东西,搞不明白怎么回事!
在我看来若不是自己从零开始老老实实的开发,还不如在AutoCAD的基础上把专业技术的二次开发做好。
作者 : terenas(風) 貼文超過200則
[ 貼文 490 | 人氣 7440 | 評價 680 | 評價/貼文 1.39 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2011/4/2 下午 06:39:34

>呵呵,所以我并不大喜欢利用DwgDirect,我想要么就直接读Dwg,要么就乖乖的使用Autodesk提供的API.
>看了青衫你的说明,我再去看英文的,就容易明白多了!谢谢青衫!
>期待青衫有更多的文字出来!
>现在大陆有一大堆仿造AutoCAD的东西,搞不明白怎么回事!
>在我看来若不是自己从零开始老老实实的开发,还不如在AutoCAD的基础上把专业技术的二次开发做好。
當然, 若只著眼在賺錢這個短線的方向, 倒不是錯. 但長線看.
自己開發的好處是, 技術知識始終在你自己手上.
很多東西, 自己沒動手做過, 根本不知問題出在何處.
作者 : bensontan(Benson) 貼文超過1000則人氣指數超過30000點
[ 貼文 1056 | 人氣 40462 | 評價 3290 | 評價/貼文 3.12 | 送出評價 80 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/2/6 下午 12:16:37
今天才知道青衫大大在威知!

那你一定認得我學長楊明瀚∼
 板主 : Jammy , simula
 > 一般討論區 - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - 一般討論區 - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
一般討論區
1 青衫 5370 
2 HKLN.net 1370 
3 冼鏡光 650 
4 simula 610 
5 joe 560 
6 DEMO999 520 
7 小朱 490 
8 jonay 480 
9 BlueTulip 460 
10 Jammy 370 
一般討論區
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.1721191