20230814-CAD中的dxf文件解析:准备工作

https://blog.csdn.net/weixin_40196271/article/details/106431821

1. 引言

CAD 是工程中常见的画图软件,dxf 是cad中经常用到的文件,在工作中有用到对dxf文件进行解析的情况。这篇文章将说明如何用代码将dxf文件中的信息解析出来。

2. dxf 文件

dxf 是一种开放的矢量数据格式,可以分为两类:

ASCII格式和二进制格式;ASCII具有可读性好的特点,但占用的空间较大;二进制格式则占用的空间小、读取速度快。

DXF文件是由很多的”代码”和”值”组成的”数据对”构造而成,这里的代码称为”组码”(group code),指定其后的值的类型和用途。每个组码和值必须为单独的一行的。

DXF文件是由很多的”代码”和”值”组成的”数据对”构造而成,这里的代码称为”组码”(group code),指定其后的值的类型和用途。每个组码和值必须为单独的一行的。

.dxf 图纸的精度不如 dwg 图纸高

dxf 格式确实会造成数据丢失,并且不支持自定义对象,在bricsCAD中您不会想用这个来保存数据,因为bricsCAD创建的数据实在是太多了,这个格式只在文件导入或者导出时比较好用,

同一图纸的文件大小:

DXF (ASCII) 1116 KB
DXF(binary二进制)581kb
DWG 16 KB


DXF 文件的基本组成如下所示:

●HEADER 部分 - 图的总体信息。每个参数都有一个变量名和相应的值。

●CLASSES 部分 - 包括应用程序定义的类的信息,这些实例将显示在 BLOCKS、ENTITIES 以及

●OBJECTS 部分-通常不包括用于充分用于与其它应用程序交互的信息。

●TABLES 部分 - 这部分包括命名条目的定义。

Application ID (APPID) 表

Block Recod (BLOCK_RECORD) 表

Dimension Style (DIMSTYPE) 表

Layer (LAYER) 表

Linetype (LTYPE) 表

Text style (STYLE) 表

User Coordinate System (UCS) 表

View (VIEW)表

Viewport configuration (VPORT) 表

●BLOCKS 部分- 这部分包括 Block Definition 实体用于定义每个 Block 的组成。

●ENTITIES 部分 - 这部分是绘图实体,包括 Block References 在内。

●OBJECTS 部分 – 包括非图形对象的数据,供 AutoLISP 以及 ObjectARX应用程序所使用。

●THUMBNAILIMAGE 部分 – 包括 DXF 文件的预览图。

●END OF FILE

3.开始进入解析(先从文件的ASCII码中的组码解析)

需要准备dxf的解析库dxflib,链接如下:

https://download.csdn.net/download/weixin_40196271/12471365

以及在CAD中安装好帮助文件。可以去官网进行下载,需要安装在CAD中

https://knowledge.autodesk.com/zh-hans/support/autocad/learn-explore/caas/downloads/downloads/CHS/content/download-install-autocad-2021-product-help.html

也可以用下面的链接进行下载,直接的帮助文档

https://download.csdn.net/download/weixin_40196271/12471381

一般我们需要解析的部分会有两个,一个是dxf中的层的信息,一个是具体的图中的线,圆,圆弧,多段线等信息。

先来解析层。

(1)层的解析

层信息可以通过TABLES部分来进行解析。以下是帮助文档中对layer做的说明,打开dxf文件,查找到TABLES中layer的部分,可以对照找到相关的层的信息。

dxflib中也是通过组码的信息来解析具体信息的。通常层信息比较有用的是图层名的信息。

(2)线的解析

线的信息可以通过ENTITIES部分来进行解析。以下是帮助文档中对line的说明。

其中10,20,30后面对应的数字为起点的x,y,z左边,11,21,31后面对应的数字为终点的x,y,z坐标。

(3)圆的解析

圆的信息可以通过ENTITIES部分来进行解析。以下是帮助文档中对circle的说明。

其中10,20,30为x,y,z对应的圆心坐标,40为圆的半径。

(4)圆弧的解析

圆弧的信息可以通过ENTITIES部分来进行解析。以下是帮助文档中对arc的说明。

其中,10,20,30为x,y,z的圆心坐标,40为圆的半径,50为圆的起点角度(弧度制),51为圆的终点角度(角度制)

(5)多段线的解析

多段线的信息可以通过ENTITIES部分来进行解析。多段线是由多个角点连接起来的。一般我们解析LWPOLYLINE,POLYLINE属于旧版本了,不过有的时候也会出现。以下是帮助文档中对lwpolyline的说明:

其中,90为多段线中角点的个数,10,20为多段线中的角点的x,y坐标,42为角点的凸度,为角点对应的圆弧的圆心角的四分之一的正切(这么说有点复杂,后面会具体讲到)。一般我们会把角点信息进一步解析出来,变成线和圆的信息。

(6)椭圆的解析

椭圆的信息可以通过ENTITIES部分来进行解析。以下是帮助文档中对ellipse的说明。

其中,10,20,30为椭圆圆心的x,y,z坐标。11,21,31为相对于中心的长轴端点的x,y,z坐标,40为短轴与长轴的比例,可以用来计算长短轴半径。41,42为起始和终止角度(弧度制)。

2.dxflib中文件说明

下载好dxflib后,我们可以试运行它的demo,发现:

dl_entities.h:这里面是定义点,线,圆,圆弧,多段线,角点等的结构体的文件(DL_CircleData,DL_PointData等)

dl_dxf.h,dl_dxf.cpp:这里面是具体的对点,线,圆,圆弧,多段线等的解析,如果需要导出需要的点,线,圆,圆弧,多段线的信息(具体可以看addpoint, addline, addcircle, addpolyline, addarc等函数),可以从这里增加容器等导出数据。

dl_wirter_ascii.cpp:这里是要写入dxf时用到的文件,具体的我还在研究。

测试demo时,我发现demo并不能直接用,比如我的dxf文件在cad中进行修改后,会输出一些多余的信息。所以要在上一篇说的那样,从ENTITIES中入手,在ENTITIES的部分去寻找,可以在dl_dxf.cpp的processDXFGroup函数中入手修改去进行查找。

另外一个就是块的问题,如果插入块,ENTITIES中会有INSERT,并且下面还有块名,而真正的块信息还在BLOCKS中。所以块的信息需要去BLOCKS中找到对应的块名再进一步进行解析,并且解析完块要记得与后面的ENTITIES中的数据分离开来,不然会出现二次解析。

具体的层,点,线,圆,圆弧等解析代码就不放出来了,建议自己去demo里面看。还需要提醒的是,圆弧的角度单位为角度制,而椭圆的为弧度制。

3.总结

这篇简要的说明了一下dxflib中的一些文件的情况,以及实际应用中遇到的问题。下一篇中将主要对多段线解析成线和圆弧进行说明。

关于官方demo文件的下载,还可以参考:

dxflib-src.rar_dxflib-互联网文档类资源-CSDN下载

Dxf_C帮助文档.zip-互联网文档类资源-CSDN下载

今天主要说一下多段线数据的解析。

2.多段线数据的解析

先看看多段线长什么样子

直观上看,多段线由线和圆弧构成,但是相邻的线、圆弧是连接起来的。但是从多段线在含义上看来,它其实是由一个个角点连接起来的。

如下面图1为一个多段线,图2所示,为dxf文本中对多段线的描述,LWPOLYLINE标记着进入多段线的描述(文件保存版本为2000以上),如果是POLYLINE则表示为比较老的标本。图3为对polyline的组码的说明,其中10,20之后的数据为角点的x,y坐标,42之后的数据为角点的凸度,其中为负说明圆弧的方向为顺时针方向,为正说明圆弧方向为逆时针方向。

图1.多段线 图2.多段线的dxf文本 图3.多段线的组码说明

如上面所说,多段线是由线和圆弧组成,对于线的话,则42后的数据为0或者没有,线的解析直接就是线起点和线终点。

如果42后的数据不为0,则角点和角点之间连接的为圆弧,圆弧的起点和终点也就是相邻角点的坐标,关键是怎么利用凸度的信息。

我们在CAD的help中找到对凸度的解释:凸度是四分之一圆弧段角的切线,如果从起点到端点,圆弧为顺时针,则为负数。凸度为 0 表示一条直线段,角点为连接直线的两个端点。凸度为 1 表示一个半圆。

凸度不为0时为圆弧,那如何来得到圆弧的圆心和半径信息呢?

这里我觉得yishang44这里解释的挺好,放上他计算的链接:

dxf中凸度的计算_yishang44的博客-CSDN博客_dxf凸度

为了防止他博客丢失,我在这里抛转做一些解释和说明吧。前面说到CAD里的说法是:凸度是四分之一圆弧段角的切线,这里用的是yishang44的图。

如果A1,A2为两个角点,那么四分之一圆弧角为图中,为圆周角,的圆心角,很显然。则A1,A2两个角点的凸度为。那现在

已知:角点A1,A2的坐标,

求:圆心、半径

这里用的方法是旋转变换公式来的,以A1,A2的中点A0为旋转中心,(r-H)为半径的点B进行顺时针旋转90°来得到圆心O,x0,y0为A0坐标,x,y为B坐标,其中B坐标可以根据向量公式来得到,其中

旋转公式为:

这里的角度为90°,则公式变为:

算得圆心坐标为:

注意事项:(1)如果用线段和圆弧元素来表示多段线,需要注意排序问题和数量问题;

(2)有的时候会判断多段线是否封闭,要看70后面的数值,如果是0则不封闭,为0是封闭的。

暂时先写这么多。。。。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2024 TeX_baitu
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~