用人话说说AutoCAD的DXF格式

2022-04-25
  1. AutoCAD
  2. DXF
  3. 技术
  4. 中文

什么是DXF格式

DXF是AutoCAD(Drawing Interchange Format或者Drawing Exchange Format) 绘图交换文件。DXF 是Autodesk(欧特克)公司开发的用于AutoCAD与其它软件之间进行CAD数据交换的CAD数据文件格式。

说人话:DXF是一个专门开放给第三方开发者图形数据格式。

为什么选择用DXF格式

AutoCAD——画图用的,我们都熟悉,常见的保存格式是.dwg,但是DWG是AutoCAD的私有格式,格式细节没有公开,第三方开发者很难下手。
DXF是Autodesk专门开放给第三方开发者的文件格式,也是受到AutoCAD直接支持的一种格式。开发者想实现自动化绘图的需求,Autodesk官方也是推荐你从DXF入手。

而且DXF和DWG并非完全不可转换,ODAFileConverter是一个免费的,由ODA组织(偏官方性质的)推出的一个跨文件版本的DWG,DXF文件互转工具,而且支持命令行形式的使用。
哪怕你最终生成的格式必须是DWG的格式,也可以使用上述软件间接地实现你的需求。

说人话:DXF和DWG,都是正经的受AutoCAD支持的格式。想实现程序自动化绘图,或者其他需求时,DWG你先别碰,从DXF下手吧。

DXF格式文件长啥样

我们打开AutoCAD 2020在图纸中只画一个原点在(0,0),半径为1的圆,保存为.dxf格式,然后用任意文本编辑器打开,你将会看到:

  0
SECTION
  2
HEADER
  9
$ACADVER
  1
AC1015
...
...
CIRCLE
  5
293
330
1F
100
AcDbEntity
  8
0
100
AcDbCircle
 10
0.0
 20
0.0
 30
0.0
 40
1.0
  0
ENDSEC
...
...
RTVSPropertyOp62
 70
     1
  0
ENDSEC
  0
EOF

首先,你可以看到它是能正常打开的文本格式,你可以直观的查看,编辑它;粗略的浏览下来,能感受到它是有一定格式的。

下边我们正式开始看看DXF的组成。

DXF的组成

DXF中的基本概念

DXF™ 格式是 AutoCAD ® 图形文件中包含的所有信息的一种带标记数据的表示方式。带标记数据是指文件中的每个数据元素前面都带有一个称为组码的整数。组码的值表明了随后的数据元素的类型。还指出了数据元素对于给定对象(或记录)类型的含义。 ——《DXF 参考手册》

提取一下,说人话就是: 组码,就是一个整数,后边跟着的那个就是数据元素;组码+数据元素 = 带标记数据 ; 所有带标记数据之和 = DXF文件

以上边实例最开始那几行为例:

  0       <- 组码,0表示图元类型的字符串,后边能跟的数据元素是固定的几个,如:SECTION,ENDSEC,EOF...
SECTION   <- 数据元素,图元类型:SECTION,表示下边是一段的开始(HEADER,CLASSES,ENTITIES...这都算一段,具体看下边整体结构部分)

  2       <- 组码,2表示名称
HEADER    <- 数据元素,名称:HEADER(和组码含义对应),代表这一段是HEADER段

  9       <- 组码,9表示变量名称标识符(仅在 DXF 文件的 HEADER 段中使用)
$ACADVER  <- 数据元素,变量名称:$ACADVER,代表AutoCAD 图形数据库版本号(DXF文件版本号)

  1       <- 组码,1表示下边跟的是$ACADVER变量的值
AC1015    <- 数据元素,$ACADVER变量值为AC1015,AC1015则代表当前DXF版本为AutoCAD 2000版

对DXF中的基本概念有一些了解之后,接下来我们来看一个DXF文件的整体结构。

DXF整体结构

正如一篇文章有题目,章节标题,段落主题,段落内容一样,DXF文件内也是类似的树状结构。

搞了个思维导图,看的更清楚一些:

上边这个思维导图已经表述的很全面了,简单总结一下:

  1. DXF由6部分(段)组成(忽略THUMBNAILIMAGE段),分别是:HEADER段,OBJECTS段,ENTITIES段,BLOCKS段,TABLES段,CLASSES段;
  2. 每一段的开始都会有 0 SECTION 2 XXXX 来标识下边是哪一段;
  3. 点,线,圆等图形数据,都定义在ENTITIES段,需要重点关注。

既然ENTITIES段对于我们来说最重要,那么下边我们简单分析一下ENTITIES段的内容。

ENTITIES段简析

ENTITIES段包含了几乎所有图形对象,以一个CIRCLE(圆)和一个LINE(线)为例,我们来看一下ENTITIES的结构,以及图形对象是在ENTITIES段存在的。

                         ......
|----------|-----------------------------------
|          |                        0           <- 组码
|          |段头,标志ENTITIES段     SECTION     <- 数据元素,段开始标识
|          |       的开始              2         <- 组码,段名称
|          |                        ENTITIES    <- 数据元素,当前段为ENTITIES段
|          |----------|------------------------ 上边这一部分是定义ENTITIES段
|          |          |                0         <- 组码
|          |          |              CIRCLE      <- 数据元素,这是一个圆
|          |          |                5         <- 组码,句柄(handle),可以理解为一个ID,不能重复
|          |          |              293         <- 数据元素,句柄值
|          |          |              330         <- 组码,所有者 BLOCK_RECORD 对象的软指针 ID/句柄
|          |          |              1F          <- 数据元素,软指针 ID
|          |          |              100         <- 组码,子类标记 (AcDbEntity)
|          |          |CIRCLE        AcDbEntity  <- 数据元素,固定为AcDbEntity
|          |          |  圆            8         <- 组码,图层名
|          |          |              0           <- 数据元素,图层名:0,代表在0图层(默认图层)上
|          |          |              100         <- 组码,子类标记 (AcDbCircle)
|          |          |              AcDbCircle  <- 数据元素,固定为AcDbCircle
|          |          |               10         <- 组码,中心点X 值
|          |          |              0.0         <- 数据元素,X 值:0.0
|          |          |               20         <- 组码,中心点Y 值
|          |          |              0.0         <- 数据元素,Y 值:0.0
|          |          |               30         <- 组码,中心点Z 值
|          |          |              0.0         <- 数据元素,Z 值:0.0
|          |          |               40         <- 组码,半径
|ENTITIES段|          |              1.0         <- 数据元素,半径为1
|  数据    | 图形数据  |-----------------------  上边这一部分完成对CIRCLE(圆)的定义,对圆心(0,0,0)和半径(1)都进行了赋值
|          |          |             0           <- 组码,
|          |          |             LINE        <- 数据元素,这是一条线
|          |          |               5         <- 组码,句柄(handle),可以理解为一个ID,不能重复
|          |          |             2CC         <- 数据元素,句柄值
|          |          |             330         <- 组码,所有者 BLOCK_RECORD 对象的软指针 ID/句柄
|          |          |             1F          <- 数据元素,软指针 ID
|          |          |             100         <- 组码,子类标记 (AcDbEntity)
|          |          |             AcDbEntity  <- 数据元素,固定为AcDbEntity
|          |          |               8         <- 组码,图层名
|          |          |  LINE       0           <- 数据元素,图层名:0,代表在0图层(默认图层)上
|          |          |   线        100         <- 组码,子类标记 (AcDbLine)
|          |          |             AcDbLine    <- 数据元素,固定为AcDbLine
|          |          |              10         <- 组码,起点X
|          |          |             3.0         <- 数据元素,起点X=3.0
|          |          |              20         <- 组码,起点Y
|          |          |             0.0         <- 数据元素,起点Y=0.0
|          |          |              30         <- 组码,起点Z
|          |          |             0.0         <- 数据元素,起点Z=0.0
|          |          |              11         <- 组码,端点X
|          |          |             6.0         <- 数据元素,端点X=6.0
|          |          |              21         <- 组码,端点Y
|          |          |             6.0         <- 数据元素,端点Y=6.0
|          |          |              31         <- 组码,端点Z
|          |          |             0.0         <- 数据元素,端点Z=0.0
|          |----------|---------------------- 上边这一部分完成对LINE(线)的定义,完成起点(3,0,0)和端点(6,6,0)的赋值
|          | 段尾,ENTITIES段        0         <- 组码
|          |     结束               ENDSEC      <- 数据元素,段结束标志
|----------|--------------------------------- 段结束
                         ......

这时候问题来了,为什么0下边就要跟CIRCLE,10就代表的圆心X呢?

因为它就是这么规定的,如下图所示,100对应子类标记AcDbCircle,10,20,30分别对应圆心的X,Y,Z值。 image

所有的组码对应的含义,以及下边所跟值的说明都可以在又臭又长的官方文档中找到答案:《DXF 参考手册》

结语

看到这里应该对DXF的整体结构有了大概的了解了,DXF格式虽然有点奇怪,但也有规律可循,接下来你就可以对着官方文档去实现自己的需求了。

文档:

CAD工具:

几个DXF读写库:


本文完