资源预览内容
第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
第9页 / 共9页
亲,该文档总共9页全部预览完了,如果喜欢就下载吧!
资源描述
读取 DXF 格式文件OpenGL 是美国 SGI 公司最新推出的一套开放式的三维图形软件接口,适用于广 泛的计算机 环境,从个人计算机到工作站,OpenGL 都能实现高性能的三维图形功能。 OpenGL 本身不 仅提供对简单图元的操作和控制,还提供了许多函数用于复杂物体的建模。但 是,我们 通常喜欢使用 AutoCAD 和 3DS 及 3Dmax 等工具来建立模型,并且我们已经有了 很多这样的模 型,那么我们如何才能资源共享,避免重复劳动呢?利用 CAD 图形标准数据交 换格式D XF 格式,我们就能很容易地实现资源共享,而不需要重复建模。 DXF 文件的结构很清楚,具体如下: 1. 标题段(HEADER ) 有关图形的一般信息都可以 DXF 文件的这一节找到,每一个参数具有一个变量 名和一个 相关值。 2. 表段 这一段包含的指定项的定义,它包括: a、 线形表(LTYPE) b、 层表(LYER) c、 字体表(STYLE) d、 视图表(VIEW) e、 用户坐标系统表(UCS) f、 视窗配置表(VPORT) g、 标注字体表(DIMSTYLE) h、 申请符号表(APPID) 3. 块段(BLOCKS) 这一段含有块定义实体,这些实体描述了图形种组成每个块的实体。 4. 实体段(ENTITIES ) 这一段含有实体,包括任何块的调用。 5. END OF FILE(文件结束) 下面是对 DXF 的基本结构举一实例进行说明: 0 0 后接 SECTION SECTION 表明这是一个段的开始2 2 后接的是段名 HEADER 说明该段是 HEADER 段(标题段) 9 $ACADVER 文件是由 AUTOCAD 产生的 1 AC1008 9 9 后接 $UCSORG $UCSORG 用户坐标系原点在世界坐标系中的坐标 10 10 对应 X 0.0 X 的值 20 20 对应 Y 0.0 Y 的值 30 30 对应 Z 0.0 Z 的值 9 $UCSXDIR 这是一段不太相关的部分,略去 10 1.0 . . 9 9 后接 $EXTMIN $EXTMIN 说明三维实体模型在世界坐标系中的最小值 10 10 对应 X -163.925293 X 的值 20 20 对应 Y -18.5415860.0 Y 的值 30 30 对应 Z 78.350945 Z 的值 9 9 后接 $EXTMAN $EXTMAX 说明三维实体模型在世界坐标系中的最大值 10 10 对应 X 202.492279 X 的值 20 20 对应 Y 112.634300 Y 的值 30 30 对应 Z 169.945602 Z 的值 0 0 后接 ENDSEC ENDSEC 说明这一段结束了 0 0 后接 SECTION SECTION 表明这是一个段的开始 2 2 后接的是段名 TABLES 说明该段是 TABLES 段(表段) . . . . 该段对我们不太相关,此处略去不进行说明 0 0 后接 ENDSEC ENDSEC 说明这一段结束了0 0 后接 SECTION SECTION 表明这是一个段的开始 2 2 后接的是段名 ENTITIES 说明该段是 ENTITIES 段(实体段)这是我 0 们要详细说明的段,该段包含了所有实体的 POLYLINE 点的坐标和组成面的点序。0 后接 POLYLINE 8 表明以下数据是对于一个新的实体; OBJECT01 8 后接的字符串是这个实体的名称 66 1 70 从 66 1 到 70 64 64 说明该实体是由许多小平面组成的 71 38 71 38 说明该实体共有 38 个点 72 72 72 72 说明该实体由 72 个三角形构成 0 0 VERTEX VERTEX 表明后面紧跟着的是实体的数据 8 OBJECT01 10 对应 X 坐标 -163.925293 X 的值 20 对应 Y 坐标 -17.772665 Y 的值 30 对应 Z 坐标 128.929947 Z 的值 70 70 192 192 表明上面的数据信息是点的坐标 0 每一个从 0 VERTEX 到 70 192 之间 VERTEX 的一小段是点的坐标 . . . 70 192 0 VERTEX 8 OBJECT01 10 0 20 0 30 0 当 70 后跟 128 时,表明该实体的每个点的坐标数据已经记录 70 完了,下面紧跟着的是记录这些点是以什么样的方式组合成各128 个三角形。 71 71、72、73 后面跟着的值表明某一个三角形是第二个、第 2 一个、第四个点构成的,点的顺序是按照记入 DXF 文件的顺 72 序。当某一值为负数时,则表明该点到下一点的线不要画出, 1 如果要画三维实体的线型图,就必须使用这一特性,否则线条 73 将会出现紊乱。 -4 0 VERTEX . . . . 0 0 后接 SEQEND 表明该实体的数据已经全部记录完了 SEQEND 8 OBJECT01 0 POLYLINE 0 后接 POLYLINE 表明以下又是一个新的实体 . . . . 0 ENDSEC 0 后接 ENDSEC 表明这是该段的结尾 0 EOF 0 后接 EOF 表明这个 DXF 文件结束了 在 DXF 文件中,我们最关心的是如何得到模型上各个点的坐标,并且用这些点 连成许多个 三用形,构成面,进而绘制出整个模型。在 DXF 文件的结构中,我们已经看到, DXF 文件 先叙述实体上各个点的坐标,然后叙述实体上有多少个面,每个面由哪些点构 成。这样 ,我们至少需要 2 个数组来存储一个实体的信息,一个用于存储点的坐标,一 个用于存储 点序,我们可以把这 2 个数组放到一个结构中,如果模型中实体的数目不止一 个是,我们 就用这个结构来定义一个数组。在本文中,我们使用 Visual C+ 6.0 来写一 个读取 DX F 文件的小程序。 在实际应用中,模型中实体的数目以及实体中点和面的数目都是不定的,为了 有效地利 用内存,我们选择 MFC 类库中的聚合类 CobArray 类所创建的对象 vertex, sequence 来存储 和管理实体的点坐标和点序。 CObArray 类是一个用来存放数组类的聚合类,它能根据要存进来的数组(或结 构)多少 自动进行自身大小的高速,而且这个类本身具有的成员函数使得我们对它的对 象的操作 更加方便、快捷,用它编的程序也易于读懂。三维实体模型的模型信息中的一部分信息可以在标题段中读出,通过读取变量 名为UC SORG 的三个变量,可以得到三维实体在世界坐标系中自身所定义的用户坐标系 原点的三 维坐标。通过读取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 obName20; 定义结构 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 中有一个 VERTEX 结构的变量:m_vertex,信息实际上 是存储在 这个变量中的,函数 CVertex(VERTEX 存入 CObArray 对象中。 ; class CSequence : public CObject 这也是一个由 CObject 类派生的类,作用和刚才 CVertex 类一样,protected: 只不过 Csequence 类是用来存储实体中面的组成(点序)的。 CSequence(); DECLARE_DYNCREATE(CSequence) virtual CSequence(); public: CSequence(SEQUENCE SEQUENCE m_sequence; ; 声明好结构与类后,我们还需要建立一个.CPP 文件,来定义几个函数。 IMPLEMENT_DYNCREATE(CVertex,CObject) CVertex:CVertex() CVertex:CVertex() 构造函数和销毁函数都是空的 CVertex:CVertex(VERTEX 它是这个类中最重要的一环。 IMPLEMENT_DYNCREATE(CSequence,CObject) CSequence:CSequence() Csequence 类的定义与 CVertex 类的定义差不多,只是其中的参数 m_sequence 的类型和 CVertex 类中的参数 my_vertex 的类型不一样 CSequence:CSequence() CSequence:CSequence(SEQUENCE 然后用结构 myVertex(如前所定义)定义一个指针*myData,目的在于根据模 型中实体的 多少来给指针分配合适的内存,使之成为结构数组。 定义一个函数,用于确定模型中有多少个实体,函数的返回值就是实体的个数。int CJupiterView:getObjectNumber() char str110,str210; char name=“theFirst“; int num; num=0; FILE* fp;fp=fopen(“data.dxf“,“r“); 打开 DXF 文件,data.dxf while(! feof(fp) 实体数就加一。 if(strcmp(str1,“VERTEX“)=0) fscanf(fp,“%sn“,str2); 打开 DXF 文件,data.dxf fscanf(fp,“%sn“,str2) ;这个函数是根据实体的名字来判断实体的个数的 if(strcmp(name,str2) != 0) 所以函数只读取实体的名字,一旦出现新的实体 名字, 实体数就加一。 strcpy(name,str2); num+; fclose(fp); return num; 以下是读取实体点的坐标以及点序的程序代码,在这个程序中,读取了模型中 点的坐标 的最大值与最小值、实体的名字、点的坐标,以及点序。 void CJupiterView:OnFileInput() / TODO: Add
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号