用VC++读取DXF文件格式的源代码和相关资料.docx

上传人:b****3 文档编号:26661877 上传时间:2023-06-21 格式:DOCX 页数:18 大小:21.05KB
下载 相关 举报
用VC++读取DXF文件格式的源代码和相关资料.docx_第1页
第1页 / 共18页
用VC++读取DXF文件格式的源代码和相关资料.docx_第2页
第2页 / 共18页
用VC++读取DXF文件格式的源代码和相关资料.docx_第3页
第3页 / 共18页
用VC++读取DXF文件格式的源代码和相关资料.docx_第4页
第4页 / 共18页
用VC++读取DXF文件格式的源代码和相关资料.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

用VC++读取DXF文件格式的源代码和相关资料.docx

《用VC++读取DXF文件格式的源代码和相关资料.docx》由会员分享,可在线阅读,更多相关《用VC++读取DXF文件格式的源代码和相关资料.docx(18页珍藏版)》请在冰豆网上搜索。

用VC++读取DXF文件格式的源代码和相关资料.docx

用VC++读取DXF文件格式的源代码和相关资料

我刚找到的:

大家先看看做好了

告诉我一声

我也正准备做这个!

我们使用?

Visual?

C++?

6.0?

来写一个读取DXF文件的小程序。

  在实际应用中,模型中实体的数目以及实体中点和面的数目都是不定的,为

了有效地利用内存,我们选择MFC类库中的聚合类CobArray类所创建的对象

vertex,?

sequence来存储和管理实体的点坐标和点序。

  CObArray类是一个用来存放数组类的聚合类,它能根据要存进来的数组(或

结构)多少自动进行自身大小的高速,而且这个类本身具有的成员函数使得我们

对它的对象的操作更加方便、快捷,用它编的程序也易于读懂。

 

  三维实体模型的模型信息中的一部分信息可以在标题段中读出,通过读取变

量名为$UCSORG的三个变量,可以得到三维实体在世界坐标系中自身所定义的用

户坐标系原点的三维坐标。

通过读取$EXTMAX,$EXTMIN可以获知三维实体在世

界坐标系中的范围,而其它部分的信息只有读完了全部DXF文件后才可以通过计算

确定。

对于三维实体模型的全部点坐标、点序,可以在实体段中按照前面介绍的

DXF文件基本结构读出。

现在我们开始写这个程序。

  先建立一个头文件HEAD.H定义如下的结构:

VERTEX,?

SEQUENCE和类CVertex,?

Csequence。

  typedef?

struct?

{

  float?

x,y,z;

  }VERTEX;?

结构VERTEX用来存储点的坐标

 

  typedef?

struct?

{

  int?

a,b,c;

  }SEQUENCE;?

结构SEQUENCE用来存储实体的面的组成

 

  typedef?

struct?

{

  char?

obName[20];?

定义结构myVertex来存储实体的名字,点的坐标以及面的组成,

  CObArray?

Vertex;?

其中,点的坐标和面的组成是由聚合类CObArray定义的对象来

  CObArray?

Sequence;?

在存储的,我们可以把VERTEX结构和SEQUENCE结构加入到

  }myVertex;?

这两个对象中保存

 

  class?

CVertex?

:

?

public?

CObject

  {?

因为CObArray类的对象中只能加入由CObject派生的对象,所以

  protected:

?

我们还需要建立一个由CObject类派生的CVertex类。

在CVertex类

  CVertex();?

中有一个VERTEX结构的变量:

m_vertex,信息实际上是存储在这

  DECLARE_DYNCREATE(CVertex)?

个变量中的。

  virtual?

~CVertex();

 

  //?

Attributes

  public:

?

我们还需要建立一个由CObject类派生的CVertex类。

在CVertex类

  CVertex(VERTEX&?

ver);?

中有一个VERTEX结构的变量:

m_vertex,信息实际

上是存储在这个变量中的,函数CVertex(VERTEX&?

ver)把VERTEX结构的变量

  VERTEX?

m_vertex;?

存入CObArray对象中。

 

  };

 

  class?

CSequence?

:

?

public?

CObject

  {?

这也是一个由CObject类派生的类,作用和刚才CVertex类一样,

  protected:

?

只不过Csequence类是用来存储实体中面的组成(点序)的。

  CSequence();

  DECLARE_DYNCREATE(CSequence)

  virtual?

~CSequence();

 

  public:

  CSequence(SEQUENCE&?

sequ);

  SEQUENCE?

m_sequence;

  };

 

  声明好结构与类后,我们还需要建立一个.CPP文件,来定义几个函数。

  IMPLEMENT_DYNCREATE(CVertex,CObject)

  CVertex:

:

CVertex()

  {

  }

 

  CVertex:

:

~CVertex()?

构造函数和销毁函数都是空的

  {

  }

 

  CVertex:

:

CVertex(VERTEX&?

ver)

  {?

这个函数的作用是:

把一个VERTEX结构的数据存入变量m_vertex中

  m_vertex?

=?

ver;?

它是这个类中最重要的一环。

  }

 

  IMPLEMENT_DYNCREATE(CSequence,CObject)

  CSequence:

:

CSequence()

  {

  }?

Csequence类的定义与CVertex类的定义差不多,只是其中的参数

  m_sequence的类型和CVertex类中的参数my_vertex的类型不一样

  CSequence:

:

~CSequence()

  {

  }

 

  CSequence:

:

CSequence(SEQUENCE&?

sequ)

  {

  m_sequence=sequ;

  }

对我有用[0]?

丢个板砖[0]?

引用?

|?

举报?

|?

管理

asd123asd

asd123asd

等级:

#7?

得分:

0回复于:

2004-12-1511:

45:

34

 

  然后用结构myVertex(如前所定义)定义一个指针*myData,目的在于根据模

型中实体的多少来给指针分配合适的内存,使之成为结构数组。

  定义一个函数,用于确定模型中有多少个实体,函数的返回值就是实体的个数。

  int?

CJupiterView:

:

getObjectNumber()

  {

  char?

str1[10],str2[10];

  char?

name[]="theFirst";

  int?

num;

 

  num=0;

 

  FILE*?

fp;

  fp=fopen("data.dxf","r");?

打开DXF文件,data.dxf

  while(!

?

feof(fp)?

&&?

!

?

ferror(fp))?

这个函数是根据实体的名字来判断实体的个数的

  {?

所以函数只读取实体的名字,一旦出现新的实体名字,

  fscanf(fp,"%s",str1);?

实体数就加一。

  if(strcmp(str1,"VERTEX")==0)

  {

  fscanf(fp,"%s",str2);?

打开DXF文件,data.dxf

  fscanf(fp,"%s",str2)?

;这个函数是根据实体的名字来判断实体的个数的

  if(strcmp(name,str2)?

!

=?

0)?

所以函数只读取实体的名字,一旦出现新的实体名字,

  {实体数就加一。

  strcpy(name,str2);

  num++;

  }

  }

  }

  fclose(fp);

 

  return?

num;

  }

 

  以下是读取实体点的坐标以及点序的程序代码,在这个程序中,读取了模型

中点的坐标的最大值与最小值、实体的名字、点的坐标,以及点序。

  void?

CJupiterView:

:

OnFileInput()

  {

  //?

TODO:

?

Add?

your?

command?

handler?

code?

here

  FILE*?

fp,*fp2;

  int?

i,k,j;

  float?

tempX,tempY,tempZ;

 

  float?

xMin,yMin,zMin,xMax,yMax,zMax,Max;

  int?

lab;

  char?

str1[20],str2[20],str[20],HT;

  char?

myName[20];

  int?

myNumber;

  VERTEX?

tempVertex;

  SEQUENCE?

tempSequence;

 

  typedef?

struct?

{

  float?

x,y,z,max;

  }MAX;

 

  MAX?

max;

  HT=9;

 

  objectNumber=getObjectNumber();

  myData=new?

myVertex[objectNumber];

 

  fp=fopen(FileName,"r");

 

  i=0;

  j=0;

  k=0;

 

  myNumber=-1;

  strcpy(myName,"ObjectName");

 

  while(!

?

feof(fp)?

&&?

!

?

ferror(fp))

  {

  fscanf(fp,"%s",str);

 

  if(strcmp(str,"$EXTMIN")==0)

  {

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&xMin);

 

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&yMin);

 

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&zMin);

  }

 

  if(strcmp(str,"$EXTMAX")==0)

  {

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&xMax);

 

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&yMax);

 

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&zMax);

 

  max.x=max(abs(xMax),abs(xMin));

  max.y=max(abs(yMax),abs(yMin));

  max.z=max(abs(zMax),abs(zMin));

  max.max=max(max.x,max.y);

  max.max=max(max.max,max.z);

 

 

  }

 

  if(strcmp(str,"VERTEX")?

==0)

  {

  fscanf(fp,"%s",str1);

  fscanf(fp,"%s",str1);

 

  if(strcmp(myName,str1)?

!

=?

0)

  {

  myNumber++;

  strcpy(myName,str1);

  strcpy((myData+myNumber)->obName,myName);

  }

 

 

  fscanf(fp,"%s",str2);

  fscanf(fp,"%f",&tempX);

 

  fscanf(fp,"%s",str2);

  fscanf(fp,"%f",&tempY);

 

  fscanf(fp,"%s",str2);

  fscanf(fp,"%f",&tempZ);

 

  fscanf(fp,"%d",&lab);

  fscanf(fp,"%d",&lab);

 

  if(lab?

==?

192)

  {

  tempVertex.x=tempX?

/?

max.max;

  tempVertex.y=tempY?

/?

max.max;

  tempVertex.z=tempZ?

/?

max.max;

  (myData+myNumber)->Vertex.Add(new?

CVertex(tempVertex));

 

 

  }

 

  if(lab?

==?

128)

  {

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&tempX);

 

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&tempY);

 

  fscanf(fp,"%s",str1);

  fscanf(fp,"%f",&tempZ);

 

  tempSequence.a=abs(tempX);

  tempSequence.b=abs(tempY);

  tempSequence.c=abs(tempZ);

 

  (myData+myNumber)->Sequence.Add(new?

CSequence(tempSequence));

 

  }

 

  }

  }

  fclose(fp);

  }?

?

对我有用[0]?

丢个板砖[0]?

引用?

|?

举报?

|?

管理

asd123asd

asd123asd

等级:

#8?

得分:

0回复于:

2004-12-1511:

45:

51

 

DXF数据接口

每个CAD系统都有自己的数据文件,数据文件分图形数据文件、几何模型文件和产品模型文件几种。

数据文件的格式与每个CAD系统自己的内部数据模式密切相关,而每个CAD系统自己内部的数据模式一般是不公开的,也是各不相同的。

由于用户使用的需要,就有数据交换文件概念的出现。

DXF为AutoCAD系统的图形数据文件,DXF虽然不是标准,但由于AutoCAD系统的普遍应用,使得DXF成为事实上的数据交换标准。

DXF是具有专门格式的ASCII码文本文件,它易于被其它程序处理,主要用于实现高级语言编写的程序与AutoCAD系统的连接,或其它CAD系统与AutoCAD系统交换图形文件。

1?

DXF文件结构?

一个完整的DXF文件是由四个段和一个文件结尾组成的。

其顺序如下:

(1)标题段,记录AutoCAD系统的所有标题变量的当前值或当前状态。

这些标题变量记录了AutoCAD系统的当前工作环境。

例如,AutoCAD版本号、插入基点、绘图界限、SNAP捕捉的当前状态、珊格间距、式样、当前图层名、当前线型和当前颜色等;

(2)表段,包含了四个表,每个表又包含可变数目的表项。

按照这些表在文件中出现的顺序,它们依次为线型表、图层表、字样表和视图表;

(3)块段,记录定义每一块时的块名、当前图层名、块的种类、块的插入基点及组成该块的所有成员。

块的种类分为图形块、带有属性的块和无名块三种。

无名块包括用HATCH命令生成的剖面线和用DIM命令完成的尺寸标注;

(4)元素段,记录了每个几何元素的名称、所在图层的名称、线型名、颜色号、基面高度、厚度以及有关几何数据;

(5)文件结束,标识文件结束。

 

DXF文件每个段由若干个组构成,每个组在DXF文件中占有两行。

组的第一行为组代码,它是一个非零的正整数,相当于数据类型代码,每个组代码的含义是由AutoCAD系统约定好的,以FORTRAN?

“I3”格式(即向右对齐并且用三字符字段填满空格的输出格式)输出。

组的第二行为组值,相当于数据的值,采用的格式取决于组代码指定的组的类型。

组代码和组值合起来表示一个数据的含义和它的值。

组代码范围见下表。

需要注意的是,在AutoCAD系统中组代码既用于指出如下表所示的组值的类型,又用来指出组的一般应用。

组代码的具体含义取决于实际变量、表项或元素描述,但“固定”的组代码总具有相同的含义,如组代码“8”总表示图层名。

组代码范围跟随值的类型

0-9串

10-59浮点

60-79整数

210-239浮点

999注释

1000-1009串

1010-1059浮点

1060-1079整数

表6.3?

组代码范围

 

一个DXF文件的框架如下:

0?

......段开始

SECTION?

2?

HEADER?

......该段为标题段

9

$ACADVER?

......下面依次描述所有标题变量

1

AC1003

.

.

.

0

ENDSEC?

......标题段结束

0

SECTION?

......段开始

2

TABLES?

......该段为表段

0

TABLE?

......表开始

2

LTYPE?

......该表为线型表

.

.

.

0

ENDTAB?

......线型表结束

0

TABLE?

2?

LAYER?

......图层表开始

.

.

.

0

ENDTAB?

......图层表结束

0

TABLE

2

STYLE?

......字样表开始

.

.

.

0

ENDTAB?

......字样表开始

0

TABLE

2

VIEW?

......视图表开始

.

.

.

0

ENDTAB?

......视图表结束

0

ENDSEC?

......表段结束

0

SECTION?

2

BLOCKS?

......块段开始

0

BLOCK?

......块开始

.

.

.

ENDBLK?

......块结束

.

.

.

0

ENDSEC?

......块段结束

0

SECTION

2

ENTITIES?

......元素表开始

0

xxxxxxx?

......开始的元素

.

.

.

0

xxxxxxx?

......又一个元素开始

.

.

.

0

ENDSEC?

......元素段结束

0

EOF?

......文件结束

 

2?

DXF文件接口程序设计

DXF文件格式的设计充分考虑了接口程序的需要,它能够容易地跳过没有必要关心的信息,同时又能方便地提取所需要的信息。

只要记住按何顺序处理各个组并跳过不关心的组即可。

但编写一个输出DXF文件的程序是比较困难的,因为必须保持图形的一致性以使AutoCAD系统接受它。

AutoCAD系统允许在一个DXF文件中省略许多项并且仍可获得一个合法的图形。

如果不需要设置任何标题变量,那么整个HEADER段都可以省略。

在TABLES段中的任何一个表,在不需要时也可以略去,并且事实上如果对它不作任何处理时,整个表段也可以去掉。

如果在LTYPE表中定义了线型,则该表必须在LAYER表之前出现。

如果图中没有使用块定义,则可以省略BLOCKS段。

如果有,那么它必须出现在ENTITIES段之前。

EOF必须出现在文件的末尾。

3?

DXF文件格式存在的问题

(1)由于DXF文件制定的较早,存在很多的不足。

不能完整地描述产品信息模型,产品的公差、材料等信息根本没有涉及。

即使产品的几何模型,由于仅仅保留了原有系统数据结构中的几何和部分属性信息,大量的拓扑信息已不复存在,也是不完整的;

(2)DXF文件格式也不合理,文件过于冗长,使得文件的处理、存放、传递和交换不方便。

另外,复杂的文件格式也使得编写一个读、写完整的DXF数据文件的程序接口是件不容易的工作。

随着CAD/CAM技术的发展和CAD/CAM系统应用的日益广泛,不同系统和系统不同子系统间的数据交换问题变得重要和迫切了,直接推动国家或国际上通用的数据交换文件标准的制定。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 成人教育 > 自考

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

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