用C读取DXF文件

  • 格式:docx
  • 大小:45.38 KB
  • 文档页数:20

用C读取DXF文件 Author: eryar@163.com 摘要:本文简要介绍了一下DXF文件的组成。重点讲述了怎样使用C语言来读取DXF文件中的实体信息。

关键字:C、DXF Abstract: The paper present the basic parts of DXF file. And focus on how to use C read the entity’s information from DXF file.

Key Words: C, DXF DXF是Drawing eXchangeFile的缩写,意思为图形交换文件,在工程制图中有广泛的应用,掌握了DXF文件的读写对编写CAD软件时的图形信息的交换有重要意义。它有两种格式:一种是ASCII DXF格式;一种是二进制DXF格式。ASCII DXF文件格式是ASCII 文字格式的AutoCAD图形的完整表示,这种文件格式易于被其它程序处理。二进制格式的DXF文件与ASCII格式的DXF文件包含的信息相同,但格式上二进制格式比ASCII格式更精简,能够节省百分之二十五的文件空间。AutoCAD能够更快地对其执行读写操作(通常能快五倍)。这可能是对ASCII格式的DXF文件操作时有ASCII与二进制形式的转换,因而花费时间较多。本文主要讨论ASCII格式的DXF文件,因为它可读性强。

一、ASCII格式的DXF文件的组成 先来介绍一下ASCII格式的DXF文件的组成。(小提示:打开AutoCAD,新建一个空的文件,然后再输出为DXF文件,并用记事本打开DXF文件,就可以看到它的所有代码了,这样有助于你更好地理解DXF文件的组成。还有按一下F1,打开AutoCAD的帮助文件,找到DXF参考,它是权威具体的资料。)

用记事本打开一个DXF文件,你可以发现它里面有这样一些代码: 0 SECTION 2 HEADER 9 $ACADVER 1 AC1015 „„ 即里面总是数字和字符串/数字在交替的出现。数字就叫做代码(通常称为组码),紧跟组码数字的称为关联值对。(以下内容来自DXF参考)DXF文件本质上由代码及关联值对组成。代码(通常称为组码)表明其后的值的类型。使用这些组码和值对,可以将DXF文件组织到由记录组成的区域中,这些记录由组码和数据项目组成。在DXF文件,每个组码和值各占一行。表1为组码值类型表的部分:

表1 组码值类型表(部分) 一个完整的ASCII格式的DXF文件结构如下: HEADER段。它包含图形的基本信息。它由AutoCAD数据库版本号和一些系统变量组成。每个参数都包含一个变量名称及其关联的值。

CLASSES段。包含应用程序定义的类的信息,这些类的实例出现在数据库的BLOCKS、ENTITIES和OBJECTS段中。类定义在类的层次结构中是固定不变的。

TABLES段。包含以下符号表的定义: APPID(应用程序标识表) BLOCK_RECORD(块参照表) DIMSTYLE(标注样式表) LAYER(图层表) LTYPE(线型表) STYLE(文字样式表) UCS(用户坐标系表) VIEW(视图表) VPORT(视口配置表) BLOCKS段。包含构成图形中每个块参照的块定义和图形图元。 ENTITIES段。包含图形中的图形对象(图元),其中包括块参照(插入图元)。这里的信息很重要。

OBJECTS段。包含图形中的非图形对象。除图元、符号表记录以及符号表以外的所有对象都存储在此段。OBJECTS段中的条目样例是包含多线样式和组的词典。

THUMBNAILIMAGE段。包含图形的预览图像数据。此段为可选。 每个段都以一个后跟字符串SECTION的组码0开始,其后是组码2和表示该段名称的字符串(例如,HEADER)。每个段都由定义其元素的组码和值组成。每个段都以一个后跟字符串ENDSEC的组码0结束。举两个例子:

1.以下是 DXF™文件 HEADER 段的样例: 0 HEADER 段的开始 SECTION 2 HEADER 9 每出现一个标题变量便重复一次 $ 0 HEADER 段的结尾 ENDSEC 2.以下是 DXF 文件 ENTITIES 段的样例: 0 ENTITIES 段的开始 SECTION 2 ENTITIES 0 每个图元定义有一个条目,如LINE,CIRCLE 5 330 100 AcDbEntity 8 100 AcDb . . . 0 ENTITIES 段的结尾 ENDSEC 因此你需要什么信息就可以在相应的段中寻找。例如你需要得到DXF文件的版本信息就可在HEADER段中寻找。需要图形的信息就可到ENTITIES段中寻找。

再强调一下实体段:实体段记录了除块段出现的实体以外的所有绘图实体内容,包括每个实体的名称、所在图层、线型、颜色代码等等。由于定义一个实体所有组码在某一实体的任意组码在其值与默认值相同时可以省略不写。因此用户在读取DXF文件时应注意:

1.定义一个实体的数据是以“0”组码开始,而以另一个“0”组码的出现表示结束;

2.某一实体的定义数据顺序不固定。 因此用户在编写DXF文件处理程序时不能按顺序固定的格式处理,而只能按组码的同现来记录数据。

二、读取DXF文件流程 有了以上知识就可读懂DXF文件并从中提取我们所需要的信息了,而我们所需要的信息大多在ENTITIES段中。先讲一下大概的处理方法。

输入DXF文件名 打开DXF文件 读取一个记录 HEADER TABLES ENTITIES BLOCKS EOF 处理HEADER 处理TABLES 处理ENTITIES 处理BLOCKS

结束

图2 DXF文件处理流程 如图2所示为DXF文件处理流程。可以从DXF文件中检索,当检索到与某个段时就转到那个段的处理程序去处理。如检索到HEADER段就转入HEADER 段的处理程序去处理。

图形的大部分信息都在实体ENTITIES段中,因此读取实体段的内容很重要。读取实体段的数据首先要考虑读取数据的存储方式,然后再进行后一步的处理或存入数据文件中。此处用链表结构来存储。

各个实体的数据分成两块:公共数据块和特殊数据块。公共数据块存储每个实体都具有特征参数,如所在图层,实体标识,线型名„„

特殊数据块存储每个实体特有的数据,如实体LINE,它里面有两个端点的坐标值;实体CIRCLE中有圆心坐标值和半径值等。

单个实体的数据处理方法:读取一个实体的数据首先根据组码“0”后的实体标识字符串来确定其为哪一种实体,然后再根据这个实体的具体情况来读取数据。

下面为用C具体实现的代码。因为是处理ASCII文件,只需要用到C文件处理的两个标准函数:fprintf()和fscanf()。文件中有一个位置指针,指向当前读写位置。如果顺序读写一个文件,每次读写完一个字符后,该指针自动指向下一个字符的位置。

三、读取DXF文件信息的小程序 先来看一个用C来读取HEADER段中的版本号的小程序。 view plaincopy to clipboardprint? 1. /*-------------------------------------------------- 2. 3. * Header.C 4. 5. *读取DXF文件中HEADER段中DXF文件版本号的小程序。 6. 7. * eryar@163.com 02-05-08 18:55 8. 9. *----------------------------------------------------*/ 10. 11. 12. 13. 14. 15. #include 16. 17. #include 18. 19. #include 20. 21. 22. 23. #define STRLEN 30 24. 25. 26. 27. int main(intargc, char *argv[]) 28. 29. { 30. 31. int code; /*存储组码*/ 32. 33. charcodevalue[STRLEN]; /*存储组码对应的值*/ 34. 35. FILE *dxf; /*文件指针*/ 36. 37. char filename[STRLEN]; /*文件名*/ 38. 39. char suffix[6] = ".dxf"; /*只输入文件名打开DXF文件,不用输后缀.*/ 40. 41. 42. 43. printf("请输入文件名:"); 44. 45. gets(filename); 46. 47. strcat(filename,suffix); 48. 49. 50. 51. dxf = fopen(filename,"r"); /*打开文件进行读操作*/ 52. 53. if(!dxf) { 54. 55. printf("打开文件出错!/n按任意键退出..."); 56. 57. getch(); 58. 59. exit(0); 60. 61. } 62. 63. else { 64. 65. printf("文件已经打开./n正在读取.../n"); 66. 67. } 68. 69. 70. 71. while(!feof(dxf)) { 72. 73. fscanf(dxf,"%d",&code); 74.