介绍
在我们当前的项目中,Three.js 已被广泛应用于渲染 GLTF、GLB、FBX 等主流模型格式,为项目带来了高效且流畅的三维可视化体验。然而,最近我接到了一项新任务:使用Three 渲染 DXF 文件.。
这里先介绍一下 DXF 文件格式, DXF 是一种由 CAD 绘制的数据文件格式 ,在工程设计和制造领域应用广泛.
为了解决这个问题. 我研究了目前npm 中几款不错的包,接下来我会通过一个 Demo 完整地展示我的研究思路与实现过程,以及我最终的选择。我希望通过这个 Demo,不仅能梳理自己的技术思路,还能为同样面临类似问题的开发者提供一些参考和帮助。接下来,我将逐步分享这一过程,期待与大家共同探讨与进步!
准备工作
为了快速搭建一个用于展示的 Demo 环境,我首先使用 Vite 官方提供的脚手架工具创建了一个项目,作为我们的基础服务框架。接着,我准备了一个 demo.dxf 文件,并将其放置在项目的 public 目录中,以便后续使用。同时,我对默认的 App.vue 页面进行了改造,将其调整为一个适合展示和研究 DXF 模型的简洁页面。
页面样式如下:

代码结构:

在完成基础环境的搭建之后,我便正式开启了对 DXF 文件渲染的研究与分析。在研究过程中,我重点关注了以下几个开源工具和库:dxf-parser、three-dxf、dxf-viewer 以及 three-dxf-viewer。这些工具分别从不同角度提供了对 DXF 文件的解析与渲染能力,成为我探索过程中的核心研究对象。
后续,我将逐一分析这些工具的功能特性、使用场景以及优缺点,并结合实际需求,评估它们是否能够满足我们项目的目标
方案一: dxf-parser,three-dxf组合
在几种解决方案中,我首先选择了 dxf-parser 和 three-dxf 的组合方案作为研究起点。这一组合的核心在于 dxf-parser,它专注于 DXF 文件的解析,能够将 DXF 格式的图形数据提取并转换为更易于处理的 JSON 对象。为了更全面地了解这一工具,我首先查看了其在 npm 上的官方描述。

根据 npm 的文档介绍,dxf-parser 是一个轻量级的 DXF 文件解析库,支持读取 DXF 文件并将其转换为 JavaScript 对象。它提供了一种直接且灵活的方式来处理 DXF 数据,非常适合需要自定义渲染流程的项目。同时也推荐我们结合 three-dxf,这一方案能够进一步将解析后的数据转换为 Three.js 支持的几何体,从而实现 DXF 文件的渲染。
dxf-parser描述示例

通过 dxf-parser 给出的示例,我发现它的解析方法 parseSync 要求传入的是 DXF 文件对象,而不是文件路径。这意味着单纯通过路径无法使用该方法进行解析。而在我们当前的场景中,我们拿到的是之前接口返回的 DXF 文件的路径.
所以我在 Demo 中通过 axios 请求,根据路径获取 DXF 文件数据。之后将获取到的数据传递给 dxf-parser进行解析,从而将其转换为结构化的 JSON 对象。
按照这个思路编写如下示例:

最终获取如下解析对象

接在成功解析 DXF 文件数据后,接下来我计划将解析后的 JSON 对象与 three-dxf 结合,以实现 DXF 文件的可视化渲染。然而,在深入 three-dxf 的使用方式时,我发现 npm 上的官方文档并未提供模块化使用的示例,而是仅展示了原始 JavaScript 的使用方式。

为了了解 three-dxf 的更多的使用方法,我查看了three-dxf包, 在包中发现该包提供了Viewer方法。并更加描述, 得知该方法用于渲染dxf 对象。以及该方法具有以下参数:
- data: 解析后的dxf 对象
- parent: 渲染容器
- width/height: 渲染宽度高度

根据所了解的使用方式, 我开始尝试在Demo 中导入使用.
示例

遗憾的是,当我按照前面的思考在示例引入three-dxf 并进行使用时,控制台直接抛出如下错误:

通过分析控制台的报错信息,我发现问题的根源主要来自于 troika-three-utils 和 troika-three-text 这两个包,而 troika-three-text 是 three-dxf 的依赖项。报错信息进一步表明,问题主要出现在从 three 库中导出方法时,出现了未提供的方法。接着我查看troika-three-text 包的依赖, 看到该包对于three 以来的版本如下:

而我们当前项目使用的是最新的three 版本, 因此我的猜测是由于版本不匹配或 API 变更导致的兼容性问题。
至此, 我选择了结束当前的研究, 转而研究后续的方法, 有兴趣的你可以研究一下. 放弃的主要原因有一下两点:
- 项目中主要通过url 路径返回dxf 模型地址. 手动请求获取文件资源感觉有点不符合我的预期
- three 依赖不兼容, 不可能为了一个依赖去降低three 的版本, 否则可能会带来目前项目的其他问题
方案二: dxf-viewer
接下来,我转向研究 dxf-viewer 的使用。为此,首先要清理之前的相关依赖,安装当前依赖。
// 卸载依赖
npm uninstall dxf-parser three-dxf
// 安装依赖
npm install dxf-viewer
同样, 在 npm 上 dxf-viewer 并没有提供详细的使用示例,因此我们只能去查看dxf-viewer查看该包的使用方法。截图如下:



经过对 dxf-viewer 包分析,了解它导出 DxfViewer 的类。使用时,首先需要先实例化该对象,并将目标挂载元素传递给构造函数。
之后通过调用实例的 Load 方法加载并渲染 DXF 文件. Load 方法接受一个 url 作为参数,用于指定 DXF 文件的路径。
分析完了, 开始上手修改 Demo 示例:

运行结果:

非常好, 结果成功的帮我将 DXF 文件渲染出来了!同时也验证了 dxf-viewer 的可行性。 但唯一不理想的是并没有使用到目前项目中的three。 可能也就意味着为了渲染DXF 文件,我需要重新封装一套逻辑, 没法集成到先用的three 封装中。
我选择了还是先看下第三种方案,在做最后的决定。
方案三:three-dxf-viewer
同样的配方, 先卸载之前的依赖,安装当前依赖
// 卸载依赖
npm uninstall dxf-viewer
// 安装依赖
npm install three-dxf-viewer
在three-dxf-viewer 包描述示例中提供了 getFromFile 方法,可以看出该方法的参数为DXF 文件对象。然而我还是想查看一下源码,查看是否提供了以路径作为参数的解析方法。 果然该包提供了 getFromPath 方法。 通过该方法的描述可以看出, 其参数为DXF 文件路径。

分析结束,开始修改 Demo示例:

运行结果

最终发现,通过 getFromPath 方法,仅需三行代码即可实现 DXF 文件的渲染,同时无缝衔接了项目中已封装的 Three.js 渲染逻辑。这种方式不仅简洁高效,还避免了额外封装一套独立渲染链路的工作量,完美满足了需求。因此,我决定采用getFromPath 方法来实现 DXF 文件的渲染。
总结
我通过研究和探索多种 DXF 文件渲染方案,最终选择了 three-dxf-viewer 的 getFromPath 方法来满足需求,实现工作目标。 我发现目前在网上搜索以上几个包的使用时, 都没有很详细的说明, 很多都是直接复制该包的描述文档。因此我将这个研究中对这个几个包简单的使用分享出来,希望对大家有所帮助。
如果觉得这篇文章对你有帮助,别忘了点赞加关注,获取更多实用干货!🥰