尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用C++读写DXF/DWG文件有多简单?libdxfrw从零上手完整体验

用C++读写DXF/DWG文件有多简单?libdxfrw从零上手完整体验 用C读写DXF/DWG文件有多简单libdxfrw从零上手完整体验【免费下载链接】libdxfrwC library to read and write DXF/DWG files项目地址: https://gitcode.com/gh_mirrors/li/libdxfrw那个深夜我在一台没有AutoCAD的电脑前崩溃做工程软件的朋友大概都经历过这个瞬间甲方甩来一个.dwg文件说是最新的图纸而你手头既没有装 AutoCAD也不想为一次数据提取掏几千块授权费。更麻烦的是你需要的只是图纸里的几十个坐标、几行标注文字却得先想办法打开这个格式。我当时的处理方式很原始找在线转换网站、装试用版、甚至截图后自己描点。直到有人丢给我一个叫libdxfrw的 C 库——它专门解决 DXF/DWG 文件的读写问题免费开源纯代码处理不依赖任何商业软件。这篇文章就记录我从零开始用它跑通全流程的经历。先花三分钟认识这位翻译官libdxfrw 本质上是两类文件之间的翻译官DXFAutoCAD 的文本交换格式分 ASCII 和二进制两种人类勉强能读懂也是很多软件间交换图纸的通用语言DWGAutoCAD 的原生二进制格式紧凑但结构复杂像一只上了锁的箱子。这个库能读 DXFASCII 和二进制、写 DXF同时还能解析从 R14 到 2015 版本的 DWG 文件——覆盖了近二十年的图纸版本。它不负责画图它只负责把你关心的数据从文件里抠出来或者把你的数据塞成标准格式。就像项目描述里那句大实话read and write DXF/DWG files仅此而已但它做得足够干净。第一次跑通我只花了十分钟上手比想象中顺利。仓库自带 CMake 和 Autotools 两套构建方式我用的是 CMakegit clone https://gitcode.com/gh_mirrors/li/libdxfrw cd libdxfrw mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease cmake --build .编译完成会在build/下生成静态库顺带还能得到dwg2dxf、dwg2text两个命令行小工具。如果你在 Windows 上直接打开vs2013/libdxfrw.sln编译也行想偷懒的人还能用仓库里docker/目录的 Dockerfile 一键构建各发行版的可移植包。读懂一张图从实现一个接口开始libdxfrw 的读文件思路很特别它不把数据硬塞给你而是通过回调的方式喊你。你需要写一个类继承自DRW_Interface定义在src/drw_interface.h然后按需实现那些addXxx虚函数——库每解析出一个图元就调用一次对应函数。#include libdxfrw.h #include drw_interface.h class MyReader : public DRW_Interface { public: void addLine(const DRW_Line d) override { printf(线段: (%.2f,%.2f) - (%.2f,%.2f)\n, d.basePoint.x, d.basePoint.y, d.secPoint.x, d.secPoint.y); } void addCircle(const DRW_Circle d) override { printf(圆: 圆心(%.2f,%.2f) 半径%.2f\n, d.basePoint.x, d.basePoint.y, d.radious); } // 其它虚函数给个空实现即可 }; int main() { MyReader reader; dxfRW dxf(drawing.dxf); dxf.read(reader, false); // false 表示不做 2D 挤出变换 return 0; }这段代码做的事很简单打开一个 DXF把里面每条线段、每个圆的参数打印出来。你不需要理解 DXF 那套组码 值的繁琐语法库已经把图元结构化成DRW_Line、DRW_Circle这些 C 对象了。头文件里你能看到几十个类似的回调点、弧、椭圆、多段线、样条、填充、标注、视口……基本覆盖了日常图纸的全部家当。反过来写一张图让程序自己画线读是接收写则是派发。写 DXF 时同样用dxfRW这个类直接调用writeLine、writeCircle等方法把实体交出去dxfRW dxf(output.dxf); DRW_Line line; line.basePoint {0, 0, 0}; line.secPoint {100, 100, 0}; dxf.writeLine(line); DRW_Circle circle; circle.basePoint {50, 50, 0}; circle.radious 25; dxf.writeCircle(circle);写完的文件可以直接丢进任何 CAD 软件打开。write方法还允许你指定输出版本R12、2000、2004……对应DRW::Version枚举里的AC1009、AC1015、AC1018等以及是否输出为二进制格式。这意味着你可以拿它批量生成图纸、做格式版本转换或者把程序算出来的结果画出来。DWG 这只黑匣子被拆开了一条缝DWG 的解析是 libdxfrw 的看家本领。仓库里src/intern/下按版本分好了阅读器DWG 文件版本对应的阅读器R14dwgreader15R2004dwgreader18R2007dwgreader21R2010dwgreader24R2013 / R2015dwgreader27你不需要手动选读 DWG 和读 DXF 走的是同一套接口——dxfRW处理 DXFdwgR类处理 DWG两者最终都回调到你的DRW_Interface上。仓库自带的dwg2dxf/示例就展示了完整流程读入 DWG原样写出一份 DXFcd dwg2dxf ./dwg2dxf input.dwg -v2010 output.dxf-v2010控制输出为 2010 版本加-b则输出二进制 DXF。这个工具的源码dwg2dxf/dx_iface.cpp几乎是官方文档级的参考实现——它怎么把读到的数据暂存、再逐个写出去你照抄一遍就能掌握整个库的读写套路。仓库里另一个dwg2text/示例则专门负责从图纸里提取文字内容。我踩过的坑中文变成一串乱码第一次跑通后我差点就收工了直到看到图纸里的中文标题栏变成了一堆问号。原因很常见老版本 AutoCAD 在 DXF 里存的是 GB2312代码页 CP936编码而程序里默认按本地编码去读。解决办法在src/intern/drw_textcodec.cpp里写得明明白白——这个编码转换器维护着一张从各种编码别名到标准代码页的映射表你只需要在读出文本后让它统一转成 UTF-8地区代码页典型别名简体中文ANSI_936GBK、GB2312、GB18030繁体中文ANSI_950BIG5日文ANSI_932Shift-JIS韩文ANSI_949EUCKR所以遇到乱码先别慌确认文件头声明的代码页再用toUtf8()转换一次多半就正常了。这也是处理任何老图纸的通用心法。再往里看一眼代码其实是分层排排坐整体代码结构非常清爽翻一遍就懂src/ ├── drw_interface.h # 回调接口你主要打交道的地方 ├── libdxfrw.cpp # dxfRW 读写主入口 ├── drw_entities.cpp # 各种图元的数据结构 ├── drw_objects.cpp # 图层、线型、样式等表对象 └── intern/ # 各版本 dwg 阅读器、编码转换等内部实现接口层DRW_Interface、读写层dxfRW/dwgR系列、实体层DRW_Line等彼此独立你写业务代码时只需要盯着接口层完全不用关心底层二进制细节。项目根目录的SPECIFICATIONS.md还整理了 DXF 格式的各种细节想深入研究的可以对照着看。接下来你可以拿去做什么说回开头那个深夜。后来我把这套东西做成了一个小工具批量扫描项目目录下的 DWG 文件提取每个文件的图纸编号和标题文字生成一张清单。整个过程纯命令行跑完没花一分钱没打开一次 AutoCAD。同样的思路你可以复用到很多场景做一个轻量级 CAD 查看器或图元统计工具从海量图纸里批量抽取坐标、文字做工程数据分析把程序生成的结果自动导出为可交付的 DXF 图纸给旧版 DWG 文件做批量版本转换方便兼容旧软件。libdxfrw 的边界也很清楚它只读 DWG不写 DWG对太新的版本2018 之后无能为力。但就它覆盖的范围而言它几乎是开源世界里处理 DXF/DWG 文件最省心的一站。如果你也被图纸格式折腾过不妨 clone 下来从dwg2dxf/的代码看起然后打开你的终端试一试。这一次图纸里的数据由你说了算。【免费下载链接】libdxfrwC library to read and write DXF/DWG files项目地址: https://gitcode.com/gh_mirrors/li/libdxfrw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表