浏览器中的 FreeCAD
发布于 2026 年 7 月 7 日。 一切始于一个 Hacker News 线程:LibreCAD,整个 Qt 桌面应用程序,编译为 WebAssembly 并在选项卡中运行。magik 完成了这个,然后是 OpenSCAD,模式看起来像是一种食谱——针对 WebAssembly 的 Qt、JSPI、静态依赖堆栈,以及对应用假设的线程、文件系统和 OpenGL 进行诚实审计。 显而易见的下一个问题是它的扩展性有多大。 所以这里是 FreeCAD:参数化 3D CAD、草图约束的实体建模、嵌入式 Python 和十几种工作台。 它的规模大约是另两个的一个数量级——大约150万行 C++ 和70万行 Python——现在可以在浏览器标签中运行。 从 Hacker News 线程到当前状态的移植大约花费了 4 天。 实现几乎完全由 Fable 完成,是我用来压力测试 Fable 在真正大规模复杂项目中的能力的方式。 如果这听起来像一个大的主张,那么它是可以确认的。在这四天中的每一个提示都在本文末尾逐字重现——所有四十八个提示——完整的会议记录,每个子代理和每个工作流,像一个可浏览的档案一样发布。 启动 FreeCAD → 首次加载约96 MB(压缩,Brotli)——这是一个大程序,我不会假装不是;您的浏览器在之后将其缓存。 需要一个较新的基于 Chromium 的浏览器(Chrome/Edge 137 及以上):该端口依赖于 WebAssembly JSPI,而 Firefox 和 Safari 还没有发布。 当它启动时,一个演示文档(一个带有圆柱形切割的盒子)在实时 3D 视口中打开。 本文其余部分是由 Fable 完全撰写的技术说明,以回答最紧迫的问题,但从这里开始它是一个 AI 帖子。 FreeCAD 不是一个程序;它是一个平台。 在 Qt GUI 下面是 OpenCASCADE(OCCT),工业 B-rep 几何内核;Coin3D 与 Quarter,一个驱动 3D 视图的 Open Inventor 场景图;完整的嵌入式 CPython 3.14;PySide6 / shiboken6 Qt 绑定(因此 Python 代码可以构建 Qt 界面);这一次,专门针对 FEM 工作台跨编译的 VTK 9.3 的子集和 Salome SMESH 网格生成器。 在此基础上:17 个以上的工作台——Part、Sketcher、PartDesign、Draft、Spreadsheet、Measure、Surface、Import、Mesh/MeshPart/Points/Inspection/Robot、TechDraw、Assembly、CAM、BIM、FEM、Material 以及 Start。 所有这些都静态编译成一个 196 MB 的 WebAssembly 模块,旁边是 Qt 6.11。 据我所知,其中两部分在浏览器中从未完成过:PySide6 和 pivy(Coin 绑定)在 wasm 下运行,以及 OCCT+Coin+CPython+PySide+VTK+SMESH 联合成一个单一模块。 本文的其余部分是它是如何到达那里,按照发生的顺序。 构建,按顺序 本节故意很长——请求是每个修复和每个方向,按顺序,具体性就是关键。 如果你只是想尝试一下这个应用程序,启动按钮在上面。 0 · 工具链:您必须自己构建的 Qt LibreCAD 可以使用预构建的 Qt-for-wasm。 FreeCAD 不行,有一个原因:JSPI。 FreeCAD 饱和了模态对话框——185 个 C++ exec() 站点和 156 个以上的 Python——阻塞的 Python 代码无法机械地重写为回调。 保持 QDialog::exec() 语义的唯一方法是在对话框打开时暂停 wasm 堆栈,这正是 WebAssembly JSPI(JavaScript Promise Integration)所做的。 这需要 -feature-wasm-jspi ,这需要一个从源代码构建的 Qt 。 所以 /opt/toolchains 下的工具链是为 wasm 编译的 Qt 6.11.1,其中包含 JSPI 和本地 wasm 异常,位于 Emscripten 4.0.12 的旁边,旁边是手动构建的 OCCT、CPython、ICU、Boost、Xerces、{fmt} 和 yaml-cpp 的静态前缀。 1 · 内核,首先无头 使这样一个大项目可处理的学科是内核优先:证明 OCCT + CPython + FreeCAD 应用层在 wasm 中运行,才触碰用户界面的任何像素。 FreeCAD 的 C++ 模块是 Python 扩展模块(PyMOD_INIT_FUNC),通常在运行时 dlopen。 wasm 模块中不存在 dlopen ,因此每个模块都是静态链接的,并在 Py_Initialize 之前通过 PyImport_AppendInittab 注册到解释器的 inittab 中。 随着 home 路径、Python 环境和为节点侧测试排序的 NODERAWFS 构建,FreeCADCmd 以无头模式运行——打开 .FCStd,重新计算,往返 STEP——首先在节点中,然后在浏览器中。这是首个发布的项目,它本身就是一个产品:一个可编程的 CAD 内核在一个标签中。 2 · 链接 GUI,并对 OpenGL 进行欺骗 获取完整的 GUI 目标链接主要是记账——一个共享的 inittab,一个 QProcess 代理(没有选项卡中的子进程),保护 Start 模块的时区/进程假设。 有趣的部分是 OpenGL。 FreeCAD 通过 Coin3D 进行渲染,这是诚实的1990年代固定功能 OpenGL:矩阵栈、glBegin / glVertex、glLightfv、客户端顶点数组。 WebGL2 没有上述内容。 所以链接引入了一个手写的固定功能 GL-on-GLES2 的 shim——OpenSCAD 遇到过的同一墙壁,sol
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡