为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > DXF文件格式读取(VC例子)LP

DXF文件格式读取(VC例子)LP

2017-10-10 32页 doc 89KB 65阅读

用户头像

is_601191

暂无简介

举报
DXF文件格式读取(VC例子)LPDXF文件格式读取(VC例子)LP , Download demo project - 167 Kb Introduction What is DXF? Drawing Interchange Format (DXF) files enable the interchange of drawings between AutoCAD and other programs. DXF files can be either ASCII or binary formats. Because ASCII DXF files a...
DXF文件格式读取(VC例子)LP
DXF文件格式读取(VC例子)LP , Download demo project - 167 Kb Introduction What is DXF? Drawing Interchange Format (DXF) files enable the interchange of drawings between AutoCAD and other programs. DXF files can be either ASCII or binary formats. Because ASCII DXF files are more common than the binary format, CadLib uses ASCII DXF format. What is CadLib? The CadLib is not a Computer Aided Design (CAD) program. It is a tool for creating DXF files that are used in the CAD programs. It consists of two parts. One of them is a Dynamic Link Library to create the DXF file. The other part is the programming interface. It is a class that integrates the cadio.dll functions. It can be used in Microsoft Visual C++ projects. In addition, the cadio.dll can be used in other Win32 programs. Why use CadLib? In some programs, it is needed to create a drawing output for use in other programs such as AutoCad. For example, in a "Building Detail Sheet Generator Program", the program needs to create a drawing output. And the most standard format for communicating drawing data is DXF. DXF file structure The DXF format is a tagged data representation of all the information contained in a drawing file. Tagged data means that each data element in the file is preceded by an integer number that is called a group code. A group code's value indicates what type of data element follows. This value also indicates the meaning of a data element for a given object (or record) type. Virtually all user-specified information in a drawing file can be represented in DXF format. (from AutoCad's DXF reference) A DXF file consists of some sections. Each section has some drawing data in itself. The CadLib uses the following sections: 1. HEADER 2. TABLES 3. BLOCKS 4. ENTITIES The main reference for DXF file structure that is used for CadLib is the AutoCad's DXF reference. You can find more information about DXF file structure here. Classes The classes are interfaces between CadIO.dll and the main program. "Test" has come with CadLib to demonstrate how to generate a DXF file with CDxfFileWrite and CDrawing classes. CDxfFileWrite class CDxfFileWrite gathers all the commands needed to directly create a DXF file. Usage of CDxfFileWrite is as follows: 1. Create the DXF file Collapse | Copy Code CDxfFileWrite dxffile; dxffile.Create( "d:\\test.dxf" ); 2. Begin and end the HEADER section. It's here for compatibility with some CAD programs. Others work without having HEADER section. Collapse | Copy Code // Header Section ------------------------------------------ dxffile.BeginSection(SEC_HEADER); dxffile.EndSection(); // close HEADER section ------------------------------------ 3. Begin the TABLES section and put the LAYER, LTYPE, STYLE, DIMSTYLE table-types as many as you want and then close the section Collapse | Copy Code // Tables Section ------------------------------------------ dxffile.BeginSection(SEC_TABLES); // LTYPE table type ------------------------- dxffile.BeginTableType(TAB_LTYPE); DXFLTYPE ltype; double elem[4]; // Continuous ZeroMemory(
变量便重复一次 $<变量> <组码> <值> 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段中的版本号的小程序。 /*-------------------------------------------------- * Header.C *读取DXF文件中HEADER段中DXF文件版本号的小程序。 * eryar@163.com 02-05-08 18:55 *----------------------------------------------------*/ #include #include #include #define STRLEN 30 int main(int argc, char *argv[]) { int code; /*存储组码*/ char codevalue[STRLEN]; /*存储组码对应的值*/ FILE *dxf; /*文件指针*/ char filename[STRLEN]; /*文件名*/ char suffix[6] = ".dxf"; /*只输入文件名打开DXF文件,不用输后缀.*/ printf("请输入文件名:"); gets(filename); strcat(filename,suffix); dxf = fopen(filename,"r"); /*打开文件进行读操作*/ if(!dxf) { printf("打开文件出错!\n按任意键退出..."); getch(); exit(0); } else { printf("文件已经打开.\n正在读取...\n"); } while(!feof(dxf)) { fscanf(dxf,"%d",&code); fscanf(dxf,"%s",codevalue); if(code == 2 && strcmp(codevalue,"HEADER")==0) { fscanf(dxf,"%d",&code); fscanf(dxf,"%s",codevalue); if(strcmp(codevalue,"$ACADVER")==0) { fscanf(dxf,"%d",&code); fscanf(dxf,"%s",codevalue); if(strcmp(codevalue,"AC1006")==0) { printf("AutoCAD版本为R10."); } else if(strcmp(codevalue,"AC1009")==0) { printf("AutoCAD版本为R11和R12."); } else if(strcmp(codevalue,"AC1012")==0) { printf("AutoCAD版本为R13."); } else if(strcmp(codevalue,"AC1014")==0) { printf("AutoCAD版本为R14."); } else if(strcmp(codevalue,"AC1015")==0) { printf("AutoCAD版本为AutoCAD 2000."); } else if(strcmp(codevalue,"AC1018")==0) { printf("AutoCAD版本为AutoCAD 2004."); } else { printf("不能识别的AutoCAD版本!"); break; } } } } fclose(dxf); /*关闭文件*/ printf("\n文件已经关闭."); printf("\nPress any key to halt..."); getch(); } 上述代码为打开一个DXF文件后就顺序读取只到文件结束,当遇到组码为2且组码对应的组值为字符串“HEADER”时就对HEADER段进行处理。在HEADER段中,若遇到组值“$ACADVER”时,则下一个组码对应的值就为AutoCAD的版本信息。具体版本信息可参考AutoCAD帮助文件DXF参考中的HEADER段->HEADER段组码部分。 若对理解了上述程序后,就可以读取DXF文件中实体ENTITIES部分的有用的数据了。首先要确定实体的数据结构。下面的代码为实体数据结构的定义,你也可以根据需要扩展这些实体的内容。程序的主要思路来自参考文献2。 #define STRLEN 60 #define DATASIZE sizeof(EntityData) /*-----每个实体的结构-----*/ //你可在在此添加其它的实体 //为了提高精度,变量可定义为双精度型 typedef struct tagLine{ float x1,y1,z1; float x2,y2,z2; }LINE; typedef struct tagCircle{ float x,y,z; float radius; }CIRCLE; /*------------------------*/ typedef union specialData{ LINE line; CIRCLE circle; }privateData; /*------实体的数据结构-------*/ typedef struct commonData{ char id[STRLEN]; /*实体标识字符串*/ char layer[STRLEN]; /*层名字符串*/ privateData data; /*特有数据块*/ struct commonData *next; /*用于构建链表*/ }EntityData; 定义完数据结构后,就可以用链表结构来存储实体中有用的信息了。以下程序为读取实 体LINE的有关信息的代码。 /*------------------------------------------ *Entity.C 读取实体LINE部分内容。 *eryar@163.com 02-05-08 19:52 *-------------------------------------------*/ #include #include #include #include #define STRLEN 60 #define DATASIZE sizeof(EntityData) /*-----每个实体的结构-----*/ //你可在在此添加其它的实体 typedef struct tagLine{ float x1,y1,z1; float x2,y2,z2; }LINE; typedef struct tagCircle{ float x,y,z; float radius; }CIRCLE; /*------------------------*/ typedef union specialData{ LINE line; CIRCLE circle; }privateData; typedef struct commonData{ char id[STRLEN]; /*实体标识字符串*/ char layer[STRLEN]; /*层名字符串*/ privateData data; /*特有数据块*/ struct commonData *next; /*用于构建链表*/ }EntityData; /*----------函数声明部分-----------*/ void print(EntityData *entity); /*---------------------------------*/ int main(int argc,char *argv[]) { int code; float value; char codevalue[STRLEN]; FILE *dxf; char filename[STRLEN]; char suffix[6] = ".dxf"; EntityData *entity,*entity1,*entity2; printf("请输入DXF文件名:"); gets(filename); strcat(filename,suffix); dxf = fopen(filename,"r"); if(!dxf) { printf("打开文件出错!\n可能不存在此文件.\n"); printf("按任意键退出..."); 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 && strcmp(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->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; 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 = NULL; } } 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("\nOutput LinkList:"); 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, pointer->data.line.y1,pointer->data.line.z1); printf("X2=%f\tY2=%f\tZ2=%f\n",pointer->data.line.x2, pointer->data.line.y2,pointer->data.line.z2); pointer = pointer->next; i++; }while(pointer !=NULL); } } 这个程序可以读取DXF文件中的有关直线的信息。你可以用AutoCAD绘制一些直线并另存为DXF格式,然后运行此程序,输入文件名就可以得到DXF文件中有关直线的条数和每条直线两个端点的坐标信息了。 四、总结 通过编写读取ASCII的DXF文件的有关信息的程序,对C的文件操作和ASCII的DXF文件有了一定的理解。在得到ASCII的DXF文件中的实体的信息后就可以用TC中的”graphics.h”图形操作函数或用Windows的GDI或 调用OpenGL的API绘制出相应的图形了。OpenGL的API功能强大,且对三维图形有很好的支持,因此在得到DXF文件中的有关信息后可以很方便地用OpenGL来处理得到美观的图形。 由于本人不是计算机专业的,水平有限,请多指点。
/
本文档为【DXF文件格式读取&#40;VC例子&#41;LP】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索