ImageVerifierCode 换一换
格式:DOCX , 页数:21 ,大小:22.72KB ,
资源ID:23484894      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/23484894.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(用C读取DXF文件.docx)为本站会员(b****2)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

用C读取DXF文件.docx

1、用C读取DXF文件用C读取DXF文件Author: eryar摘要:本文简要介绍了一下DXF文件的组成。重点讲述了怎样使用C语言来读取DXF文件中的实体信息。关键字:C、DXFAbstract: The paper present the basic parts of DXF file. And focus on how to use C read the entitys information from DXF file.Key Words: C, DXFDXF是Drawing eXchangeFile的缩写,意思为图形交换文件,在工程制图中有广泛的应用,掌握了DXF文件的读写对编写CAD软

2、件时的图形信息的交换有重要意义。它有两种格式:一种是ASCII DXF格式;一种是二进制DXF格式。ASCII DXF文件格式是ASCII 文字格式的AutoCAD图形的完整表示,这种文件格式易于被其它程序处理。二进制格式的DXF文件与ASCII格式的DXF文件包含的信息相同,但格式上二进制格式比ASCII格式更精简,能够节省百分之二十五的文件空间。AutoCAD能够更快地对其执行读写操作(通常能快五倍)。这可能是对ASCII格式的DXF文件操作时有ASCII与二进制形式的转换,因而花费时间较多。本文主要讨论ASCII格式的DXF文件,因为它可读性强。一、ASCII格式的DXF文件的组成先来介

3、绍一下ASCII格式的DXF文件的组成。(小提示:打开AutoCAD,新建一个空的文件,然后再输出为DXF文件,并用记事本打开DXF文件,就可以看到它的所有代码了,这样有助于你更好地理解DXF文件的组成。还有按一下F1,打开AutoCAD的帮助文件,找到DXF参考,它是权威具体的资料。)用记事本打开一个DXF文件,你可以发现它里面有这样一些代码:0SECTION2HEADER9$ACADVER1AC1015即里面总是数字和字符串/数字在交替的出现。数字就叫做代码(通常称为组码),紧跟组码数字的称为关联值对。(以下内容来自DXF参考)DXF文件本质上由代码及关联值对组成。代码(通常称为组码)表明

4、其后的值的类型。使用这些组码和值对,可以将DXF文件组织到由记录组成的区域中,这些记录由组码和数据项目组成。在DXF文件,每个组码和值各占一行。表1为组码值类型表的部分:表1 组码值类型表(部分)一个完整的ASCII格式的DXF文件结构如下:HEADER段。它包含图形的基本信息。它由AutoCAD数据库版本号和一些系统变量组成。每个参数都包含一个变量名称及其关联的值。CLASSES段。包含应用程序定义的类的信息,这些类的实例出现在数据库的BLOCKS、ENTITIES和OBJECTS段中。类定义在类的层次结构中是固定不变的。TABLES段。包含以下符号表的定义:APPID(应用程序标识表)BL

5、OCK_RECORD(块参照表)DIMSTYLE(标注样式表)LAYER(图层表)LTYPE(线型表)STYLE(文字样式表)UCS(用户坐标系表)VIEW(视图表)VPORT(视口配置表)BLOCKS段。包含构成图形中每个块参照的块定义和图形图元。ENTITIES段。包含图形中的图形对象(图元),其中包括块参照(插入图元)。这里的信息很重要。OBJECTS段。包含图形中的非图形对象。除图元、符号表记录以及符号表以外的所有对象都存储在此段。OBJECTS段中的条目样例是包含多线样式和组的词典。THUMBNAILIMAGE段。包含图形的预览图像数据。此段为可选。每个段都以一个后跟字符串SECTI

6、ON的组码0开始,其后是组码2和表示该段名称的字符串(例如,HEADER)。每个段都由定义其元素的组码和值组成。每个段都以一个后跟字符串ENDSEC的组码0结束。举两个例子:1.以下是 DXF文件 HEADER 段的样例:0 HEADER 段的开始SECTION2HEADER 9 每出现一个标题变量便重复一次$0 HEADER 段的结尾ENDSEC 2.以下是 DXF 文件 ENTITIES 段的样例:0 ENTITIES 段的开始SECTION2ENTITIES 0 每个图元定义有一个条目,如LINE,CIRCLE5330100AcDbEntity8100AcDb. . 0 ENTITIES

7、 段的结尾ENDSEC 因此你需要什么信息就可以在相应的段中寻找。例如你需要得到DXF文件的版本信息就可在HEADER段中寻找。需要图形的信息就可到ENTITIES段中寻找。再强调一下实体段:实体段记录了除块段出现的实体以外的所有绘图实体内容,包括每个实体的名称、所在图层、线型、颜色代码等等。由于定义一个实体所有组码在某一实体的任意组码在其值与默认值相同时可以省略不写。因此用户在读取DXF文件时应注意:1定义一个实体的数据是以“0”组码开始,而以另一个“0”组码的出现表示结束;2某一实体的定义数据顺序不固定。因此用户在编写DXF文件处理程序时不能按顺序固定的格式处理,而只能按组码的同现来记录数

8、据。二、读取DXF文件流程有了以上知识就可读懂DXF文件并从中提取我们所需要的信息了,而我们所需要的信息大多在ENTITIES段中。先讲一下大概的处理方法。输入DXF文件名打开DXF文件读取一个记录HEADERTABLESENTITIESBLOCKSEOF处理HEADER处理TABLES处理ENTITIES处理BLOCKS结束图2 DXF文件处理流程如图2所示为DXF文件处理流程。可以从DXF文件中检索,当检索到与某个段时就转到那个段的处理程序去处理。如检索到HEADER段就转入HEADER 段的处理程序去处理。图形的大部分信息都在实体ENTITIES段中,因此读取实体段的内容很重要。读取实体

9、段的数据首先要考虑读取数据的存储方式,然后再进行后一步的处理或存入数据文件中。此处用链表结构来存储。各个实体的数据分成两块:公共数据块和特殊数据块。公共数据块存储每个实体都具有特征参数,如所在图层,实体标识,线型名特殊数据块存储每个实体特有的数据,如实体LINE,它里面有两个端点的坐标值;实体CIRCLE中有圆心坐标值和半径值等。单个实体的数据处理方法:读取一个实体的数据首先根据组码“0”后的实体标识字符串来确定其为哪一种实体,然后再根据这个实体的具体情况来读取数据。下面为用C具体实现的代码。因为是处理ASCII文件,只需要用到C文件处理的两个标准函数:fprintf()和fscanf()。文

10、件中有一个位置指针,指向当前读写位置。如果顺序读写一个文件,每次读写完一个字符后,该指针自动指向下一个字符的位置。三、读取DXF文件信息的小程序先来看一个用C来读取HEADER段中的版本号的小程序。view plaincopy to clipboardprint?1. /*- 2. 3. * Header.C4. 5. *读取DXF文件中HEADER段中DXF文件版本号的小程序。6. 7. * eryar 02-05-08 18:55 8. 9. *-*/ 10. 11. 12. 13. 14. 15. #include 16. 17. #include 18. 19. #include 20

11、. 21. 22. 23. #define STRLEN 30 24. 25. 26. 27. int main(intargc, char *argv) 28. 29. 30. 31. int code; /*存储组码*/ 32. 33. charcodevalueSTRLEN; /*存储组码对应的值*/ 34. 35. FILE *dxf; /*文件指针*/ 36. 37. char filenameSTRLEN; /*文件名*/ 38. 39. char suffix6 = .dxf; /*只输入文件名打开DXF文件,不用输后缀.*/ 40. 41. 42. 43. printf(请输入

12、文件名:); 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)

13、72. 73. fscanf(dxf,%d,&code); 74. 75. fscanf(dxf,%s,codevalue); 76. 77. 78. 79. if(code = 2 &strcmp(codevalue,HEADER)=0) 80. 81. fscanf(dxf,%d,&code); 82. 83. fscanf(dxf,%s,codevalue); 84. 85. if(strcmp(codevalue,$ACADVER)=0) 86. 87. fscanf(dxf,%d,&code); 88. 89. fscanf(dxf,%s,codevalue); 90. 91. 92

14、. 93. if(strcmp(codevalue,AC1006)=0) 94. 95. printf(AutoCAD版本为R10.); 96. 97. 98. 99. else if(strcmp(codevalue,AC1009)=0) 100. 101. printf(AutoCAD版本为R11和R12.); 102. 103. 104. 105. else if(strcmp(codevalue,AC1012)=0) 106. printf(AutoCAD版本为R13.); 107. 108. 109. 110. else if(strcmp(codevalue,AC1014)=0)

15、111. 112. printf(AutoCAD版本为R14.); 113. 114. 115. 116. else if(strcmp(codevalue,AC1015)=0) 117. 118. printf(AutoCAD版本为AutoCAD 2000.); 119. 120. 121. 122. else if(strcmp(codevalue,AC1018)=0) 123. 124. printf(AutoCAD版本为AutoCAD 2004.); 125. 126. 127. 128. else 129. 130. printf(不能识别的AutoCAD版本!); 131. 132

16、. break; 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. fclose(dxf); /*关闭文件*/ 144. 145. printf(/n文件已经关闭.); 146. 147. printf(/nPress any key to halt.); 148. 149. getch(); 150. 151. 上述代码为打开一个DXF文件后就顺序读取只到文件结束,当遇到组码为2且组码对应的组值为字符串“HEADER”时就对HEADER段进行处理。在HEADER段中,若遇到组值“$ACADVER”时,则下一个组码对应的值就为Auto

17、CAD的版本信息。具体版本信息可参考AutoCAD帮助文件DXF参考中的HEADER段-HEADER段组码部分。若对理解了上述程序后,就可以读取DXF文件中实体ENTITIES部分的有用的数据了。首先要确定实体的数据结构。下面的代码为实体数据结构的定义,你也可以根据需要扩展这些实体的内容。程序的主要思路来自参考文献2。#define STRLEN 60#define DATASIZE sizeof(EntityData)/*-每个实体的结构-*/你可在在此添加其它的实体/为了提高精度,变量可定义为双精度型typedefstructtagLinefloat x1,y1,z1;float x2,y

18、2,z2;LINE;typedefstructtagCirclefloatx,y,z;float radius;CIRCLE;/给tagcircle起个别名叫circle/*-*/typedef union specialDataLINE line;CIRCLE circle;privateData;/*-实体的数据结构-*/typedefstructcommonDatachar idSTRLEN; /*实体标识字符串*/char layerSTRLEN; /*层名字符串*/privateData data; /*特有数据块*/structcommonData *next; /*用于构建链表*

19、/EntityData;定义完数据结构后,就可以用链表结构来存储实体中有用的信息了。以下程序为读取实体LINE的有关信息的代码。/*-*Entity.C读取实体LINE部分内容。*eryar 02-05-08 19:52*-*/#include #include #include #include #define STRLEN 60#define DATASIZE sizeof(EntityData)/*-每个实体的结构-*/你可在在此添加其它的实体typedefstructtagLinefloat x1,y1,z1;float x2,y2,z2;LINE;typedefstructtagCi

20、rclefloatx,y,z;float radius;CIRCLE;/*-*/typedef union specialDataLINE line;CIRCLE circle;privateData;typedefstructcommonDatachar idSTRLEN; /*实体标识字符串*/char layerSTRLEN; /*层名字符串*/privateData data; /*特有数据块*/structcommonData *next; /*用于构建链表*/EntityData;/*-函数声明部分-*/void print(EntityData *entity);/*-*/int

21、 main(intargc,char *argv) int code; float value; char codevalueSTRLEN; FILE *dxf; char filenameSTRLEN; char suffix6 = .dxf; EntityData *entity,*entity1,*entity2; printf(请输入DXF文件名:); gets(filename); strcat(filename,suffix); dxf = fopen(filename,r); if(!dxf) printf(打开文件出错!/n可能不存在此文件./n); printf(按任意键退出

22、.); getch(); exit(0); else printf(正在读取文件./n); entity = entity2 = (EntityData *)malloc(DATASIZE); while(!feof(dxf) fscanf(dxf,%d,&code); fscanf(dxf,%s,codevalue); if(code = 2 &strcmp(codevalue,ENTITIES)=0) while(strcmp(codevalue,ENDSEC) fscanf(dxf,%d,&code); fscanf(dxf,%s,codevalue); if(code = 0 &str

23、cmp(codevalue,LINE)=0) entity1 = (EntityData *)malloc(DATASIZE); strcpy(entity1-id,codevalue); fscanf(dxf,%d,&code); while(code) switch(code) case 8: fscanf(dxf,%s,codevalue); fscanf(dxf,%d,&code); strcpy(entity1-layer,codevalue); break; case 10: fscanf(dxf,%f,&value); fscanf(dxf,%d,&code); entity1-

24、data.line.x1 = value; break; case 20: fscanf(dxf,%f,&value); fscanf(dxf,%d,&code); entity1-data.line.y1 = value; break; case 30: fscanf(dxf,%f,&value); fscanf(dxf,%d,&code); entity1-data.line.z1 = value; break; case 11: fscanf(dxf,%f,&value); fscanf(dxf,%d,&code); entity1-data.line.x2 = value; break

25、; case 21: fscanf(dxf,%f,&value); fscanf(dxf,%d,&code); entity1-data.line.y2 = value; break; case 31: fscanf(dxf,%f,&value); fscanf(dxf,%d,&code); entity1-data.line.z2 = value; break; default: fscanf(dxf,%s,codevalue); fscanf(dxf,%d,&code); entity2-next = entity1; entity2 = entity1; entity2-next = N

26、ULL; entity = entity-next; /第一个实体区为空,所以使头指针移向下一个实体 print(entity); /输出链表printf(/nPress any key to halt.);getch();return 0;/输出链表void print(EntityData *entity) int i=0; EntityData *pointer; pointer = entity; if(pointer != NULL) do i+; pointer = pointer-next; while(pointer != NULL); printf(/nOutputLinkList:); printf(/nDXF文件中总共有%d条直线:/n,i); i = 1; pointer = entity; if(pointer != NULL) do printf(第%d条直线:/n,i); printf(X1=%f/tY1=%f/tZ1=%f/n,pointer-data.line.x1,

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1