ASCII DXF 文件
本节介绍 ASCII DXF 文件的格式。只有自行编写程序处理 DXF 文件,或者使用由 AutoLISP® 和 ObjectARX® 应用程序获得的图元信息时,才需要使用本节中包含的信息。
本节内容
- DXF 文件的基本结构
- DXF 文件中的组码
- DXF 文件中的标题组码
- DXF 文件中的类组码
- DXF 文件中的符号表组码
- DXF 文件中的块组码
- DXF 文件中的图元组码
- DXF 文件中的对象组码
- 编写 DXF 接口程序
DXF 文件的基本结构
DXF 文件本质上由代码及关联值对组成。代码(通常称为组码)表明其后的值的类型。使用这些组码和值对,可以将 DXF 文件组织到由记录组成的区域中,这些记录由组码和数据项目组成。在 DXF 文件中,每个组码和值都各占一行。
每段都以一个后跟字符串 SECTION 的组码 0 开始,其后是组码 2 和表示该段名称的字符串(例如,HEADER)。每段都由定义其元素的组码和值组成。每段都以一个后跟字符串 ENDSEC 的组码 0 结束。
从小图形中生成 DXF 文件,打印出来并在阅读本文时参考,可能会有助于用户理解本文的内容。
DXF 文件完整的结构如下:
- HEADER 段。包含图形的基本信息。它由 AutoCAD 数据库版本号和一些系统变量组成。每个参数都包含一个变量名称及其关联的值。
- CLASSES 段。包含应用程序定义的类的信息,这些类的实例出现在数据库的 BLOCKS、ENTITIES 和 OBJECTS 段中。类定义在类的层次结构中是固定不变的。
- TABLES 段。包含以下符号表的定义: APPID(应用程序标识表)BLOCK_RECORD(块参照表)DIMSTYLE(标注样式表)LAYER(图层表)LTYPE(线型表)STYLE(文字样式表)UCS(用户坐标系表)VIEW(视图表)VPORT(视口配置表)
- BLOCKS 段。包含构成图形中每个块参照的块定义和图形图元。
- ENTITIES 段。包含图形中的图形对象(图元),其中包括块参照(插入图元)。
- OBJECTS 段。包含图形中的非图形对象。除图元、符号表记录以及符号表以外的所有对象都存储在此段。OBJECTS 段中的条目样例是包含多线样式和组的词典。
- THUMBNAILIMAGE 段。包含图形的预览图像数据。此段为可选。
如果使用 SAVE 或 SAVEAS 命令的“选择对象”选项,那么所得到的 DXF 文件的 ENTITIES 区域将只包含选择的图元。
DXF 文件中的组码
组码和关联值定义对象或图元的特定方面。紧接着组码的一行是关联值。该值可以是字符串、整数或浮点值,例如点的 X
特殊组码用作文件分隔符,例如用于表示段和表的开始和结束,以及文件本身结束的标记。
图元、对象、类、表和表条目以及文件分隔符通过 0 组码(其后是用于描述该组的名称)引入。
DXF 文件字符串的最大长度是 256 个字符。如果 AutoCAD 图形中包含的字符串超出了此数字,则在执行 SAVE、SAVEAS 和 WBLOCK 时将截断那些字符串。如果 DXF 文件包含的字符串超出了此长度,OPEN 和 INSERT 命令将失败。
本节内容
- DXF 文件中的 ASCII 控制字符
DXF 文件中的 ASCII 控制字符
SAVEAS 处理文字字符串中的 ASCII 控制字符的方法是在相应的字母前面加一个插入符号 (^)。例如,将 ASCII 控制字符 G(BEL,十进制代码 7)写为 ^G。如果文字本身包含插入符,插入符将扩展为插入符和空格 (^ )。OPEN 和 INSERT 用于执行补充转换。
DXF 文件中的标题组码
应用程序可以使用 AutoLISP getvar
以下是 DXF™ 文件的 HEADER 区域的样例:
0 SECTION 2 HEADER | HEADER 段的开始 |
9 $<变量> <组码> <值> | 为每个标题变量重复一次 |
0 ENDSEC | HEADER 段的结束 |
DXF 文件中的类组码
以下是 DXF 文件 CLASSES 段的样例:
0 SECTION 2 CLASSES | CLASSES 段的开始 |
0 CLASS 1 <类 dxf 记录> 2 <类名> 3 <应用程序名> 90 <标志> 280 <标志> 281 <标志> | 为每个条目重复一次 |
0 ENDSEC | CLASSES 段的结束 |
DXF 文件中的符号表组码
以下是 DXF 文件 TABLES 段的样例。
0 SECTION 2 TABLES | TABLES 段的开始 |
0 TABLE 2 <表类型> 5 <句柄> 100 AcDbSymbolTable 70 <最大条目数量> | 通用表组码;为每个条目重复一次 |
0 <表类型> 5 <句柄> 100 AcDbSymbolTableRecord . . <数据> . | 表条目数据;为每个表记录重复一次 |
0 ENDTAB | 表的结束 |
0 ENDSEC | TABLES 段的结束 |
本节内容
- 符号表样例
符号表样例
此 DXF 序列表示三个完整的对象:符号表和两个条目。
0 | |
TABLE | 表示符号表条目 |
2 | |
STYLE | 文字样式符号表条目。这是代码 0 完全定义类型这一规则的例外情况 |
5 | |
1C | STYLE 表句柄;与图元和其他对象的句柄相同 |
70 | |
3 | 可跟随的 STYLE 表记录的最大数目(R13 版本之前的字段) |
1001 | |
APP_X | APP_X 已在符号表中放置了扩展数据 |
1040 | |
42.0 | 只是一个浮点数 |
0 | |
STYLE | STYLE 符号表中第一个元素的开始 |
5 | |
3A | 第一个条目的句柄(此处,DIMSTYLE 条目将为 105) |
2 | |
ENTRY_1 | 第一个条目的文字名称 |
70 | |
64 | 标准标志值 |
40 | |
.4 | 文字高度 |
41 | |
1.0 | 宽度比例因子 |
50 | |
0.0 | 倾斜角度 |
71 | |
0 | 文字生成标志 |
42 | |
0.4 | 上次使用的高度 |
3 | |
BUFONTS.TXT | 主要字体文件名 |
0 | |
STYLE | 第二个条目开始。第一个条目中无扩展数据或永久反应器 |
5 | |
C2 | 第二个条目的句柄 |
2 | |
ENTRY_2 | 第二个条目的文字名称 |
... | |
... | 组码 3 下的其他字段 |
3 | |
BUFONTS.TXT | 主要字体文件名和最后一个对象类型 - 特定的组 |
102 | |
{ACAD_REACTORS | 此条目有两个永久反应器 |
330 | |
3C2 | 第一个反应器对象的软 ID |
330 | |
41B | 第一个反应器对象的软 ID |
102 | |
} | 表示反应器集的结束 |
1001 | |
APP_1 | 此条目上附着的扩展数据 |
1070 | |
45 | |
1001 | |
APP_2 | |
1004 | |
18A5B3EF2C199A | |
0 | |
UCS | UCS 表的开始(以及上一个记录和表的结束) |
DXF 文件中的块组码
以下是 DXF 文件 BLOCKS 段的样例:
0 SECTION 2 BLOCKS | BLOCKS 段的开始 |
0 BLOCK 5 <句柄> 100 AcDbEntity 8 <图层> 100 AcDbBlockBegin 2 <块名> 70 <标志> 10 <X 值> 20 <Y 值> 30 <Z 值> 3 <块名> 1 <外部参照路径> | 每个块条目的开始(块图元定义) |
0 <图元类型> . . <数据> . | 块中的每个图元定义有一个条目 |
0 ENDBLK 5 <句柄> 100 AcDbBlockEnd | 每个块条目的结束(endblk 图元定义) |
0 ENDSEC | BLOCKS 段的结束 |
DXF 文件中的图元组码
以下是 DXF 文件 ENTITIES 段的样例:
0 SECTION 2 ENTITIES | ENTITIES 段的开始 |
0 <图元类型> 5 <句柄> 330 <指向所有者的指针> 100 AcDbEntity 8 <图层> 100 AcDb<类名> . . <数据> . | 每个图元定义一个条目 |
0 ENDSEC | ENTITIES 段的结束 |
DXF 文件中的对象组码
以下是 DXF 文件 OBJECTS 段的样例:
0 SECTION 2 OBJECTS | OBJECTS 段的开始 |
0 DICTIONARY 5 <句柄> 100 AcDbDictionary | 命名对象词典(根词典对象)的开始 |
3 <词典名> 350 <子对象句柄> | 为每个条目重复一次 |
0 <对象类型> . . <数据> . | 对象数据组 |
0 ENDSEC | OBJECTS 段的结束 |
编写 DXF 接口程序
通过 DXF 文件编写与 AutoCAD 通信的程序似乎比实际情况要难。使用 DXF 格式可以轻松地忽略不需要的信息,而只读取需要的信息。
本节内容
- 读取 DXF 文件
- 编写 DXF 文件
读取 DXF 文件
以下是一个简单的 Visual Basic 6 程序样例,它读取 DXF 文件,并且从给定段的给定对象中提取特定代码和值。
' ReadDXF 从 DXF 文件中提取指定的代码/值对。
' 此函数需要四个字符串参数、一个有效的 DXF
' 文件名、一个 DXF 段名、该段中对象的
' 名称以及由逗号分隔的代码列表。
'
Function ReadDXF( _
ByVal dxfFile As String, ByVal strSection As String, _
ByVal strObject As String, ByVal strCodeList As String)
Dim tmpCode, lastObj As String
Open dxfFile For Input As #1
' 获取第一个代码/值对
codes = ReadCodes
' 遍历整个文件,直到“EOF”行
While codes(1) <> "EOF"
' 如果组码为“0”,并且值为“SECTION”,则
If codes(0) = "0" And codes(1) = "SECTION" Then
' 这必须是一个新的段,以便获取下一个
' 代码/值对。
codes = ReadCodes()
' 如果此段是要获取的段,则
If codes(1) = strSection Then
' 获取下一个代码/值对,并
codes = ReadCodes
' 遍历此段,直到“ENDSEC”
While codes(1) <> "ENDSEC"
' 在某段中,所有的“0”代码都表示
' 对象。如果找到了“0”代码,则存储
' 对象名称,供以后使用。
If codes(0) = "0" Then lastObj = codes(1)
' 如果此对象是用户所需的对象,
If lastObj = strObject Then
' 则在代码前后加上逗号
tmpCode = "," & codes(0) & ","
' 如果此代码位于代码列表中,
If InStr(strCodeList, tmpCode) Then
' 则附加返回值。
ReadDXF = ReadDXF & _
codes(0) & "=" & codes(1) & vbCrLf
End If
End If
' 读取其他代码/值对
codes = ReadCodes
Wend
End If
否则
codes = ReadCodes
End If
Wend
Close #1
End Function
' ReadCodes 从打开的文件中读取两行,并返回一个包含两个项目
' 的数组、一个组码及其组码值。只要一次读取 DXF 文件中的两行代码,
' 所有程序应该都能够顺利运行。但为了使代码
' 更可靠,应该添加一些进行错误检查和其他
' 检查的代码。
'
Function ReadCodes() As Variant
Dim codeStr, valStr As String
Line Input #1, codeStr
Line Input #1, codeStr
' 修剪代码中的前导空格和后续空格
ReadCodes = Array(Trim(codeStr), valStr)
End Function
编写 DXF 文件
与编写读取 DXF 文件的程序相比,编写创建 DXF 文件的程序更困难,因为必须保持图形的一致性,这样 AutoCAD 才能找到可接受的文件。AutoCAD 使您可以省略 DXF 文件中的很多内容,而仍然能够获得可用的图形。
- 如果不设定标题变量,则可以省略整个 HEADER 区域。
- 如果不需要创建条目,则可以省略 TABLES 区域中的任何表;如果不需要 TABLES 区域中的任何内容,则可以省略整个 TABLES 区域。
- 如果在 LTYPE 表中定义了线型,则此表必须显示在 LAYER 表之前。
- 如果图形中未使用任何块定义,则可以省略 BLOCKS 段。
- 如果 BLOCKS 段存在,则该段必须出现在 ENTITIES 段之前。
- 在 ENTITIES 区域中,即使未在 LAYER 表中定义图层名,也可以参照这些图层名。系统自动使用颜色 7 和 CONTINUOUS 线型来创建此类图层。
- 文件结尾处必须存在 EOF 项目。
以下 Visual Basic 6 子例程创建了表示多边形的 DXF 文件。
' WriteDXFPolygon 创建一个最小的 DXF 文件,其中只
' 包含 ENTITIES 段。此子例程需要五个参数:
' DXF 文件名、多边形的边数、最右侧
' 一条边(这条边为竖直方向)底部端点的 X 坐标和 Y 坐标
' 以及每条边的
' 长度。注意,因为这里只要求二维点,所以
' 不包含 Z 坐标(代码 30 和 31)。直线
' 置于“多边形”图层中。
'
Sub WriteDXFPolygon( _
dxfFile As String, iSides As Integer, _
dblX As Double, dblY As Double, dblLen As Double)
Dim i As Integer
Dim dblA1, dblA, dblPI, dblNX, dblNY As Double
Open dxfFile For Output As #1
Print #1, 0
Print #1, "SECTION"
Print #1, 2
Print #1, "ENTITIES"
dblPI = Atn(1) * 4
dblA1 = (2 * dblPI) / iSides
dblA = dblPI / 2
For i = 1 To iSides
Print #1, 0
Print #1, "LINE"
Print #1, 8
Print #1, "Polygon"
Print #1, 10
Print #1, dblX
Print #1, 20
Print #1, dblY
dblNX = dblLen * Cos(dblA) + dblX
dblNY = dblLen * Sin(dblA) + dblY
Print #1, 11
Print #1, dblNX
Print #1, 21
Print #1, dblNY
dblX = dblNX
dblY = dblNY
dblA = dblA + dblA1
Next i
Print #1, 0
Print #1, "ENDSEC"
Print #1, 0
Print #1, "EOF"
Close #1
End Sub
只要在需要数据的行上写入了格式正确的项目,DXFIN 就会接受该项目。(当然,字符串项目不应该包含前导空格,除非这些空格是字符串的一部分。)此 BASIC 程序利用了输入格式的灵活性,它生成的文件与 AutoCAD 生成的文件并不完全相同。
如果使用 DXFIN 进行加载时出现错误,AutoCAD 将通过一条信息报告该错误,指明错误的性质以及检测到错误之前在 DXF 文件中处理的最后一行数据。错误可能并不出现在这一行,尤其是当出现省略所需组这样的错误时更是如此。