80 KiB
Web 版 Blender 连续执行计划
1. 文档定位
本计划用于把 blender-5.2.0 逐步变成一个浏览器中的 Blender 数据编辑器。它不是“把桌面窗口搬进 Canvas”的计划,而是以 Blender 数据和建模行为为基准,以 React 为应用界面、Three.js 为唯一浏览器渲染器、WebAssembly 为 Blender 计算核心。
存储决策:首期使用 Worker 内 IndexedDB 保存小型元数据,使用 OPFS 保存
.blend、贴图、快照和 LOD 等大文件。SQLite WASM 不属于当前必需依赖,相关
schema/migration 任务按 IndexedDB object store 执行;只有未来查询和事务需求
明确超过浏览器原生能力时,才重新立项引入 SQLite WASM。
计划中的任务按编号顺序执行。除非任务明确标注可并行,否则完成前置任务并通过验收后再开始下一项。每个任务完成后必须更新:
docs/status/<task-id>.md
tests/golden/<task-id>/
web/protocol/schema-version
任务状态只允许:todo、in_progress、blocked、done。blocked 必须记录阻塞原因、已尝试方案和下一步,不得用来隐藏未完成的实现。
2. 对标原则
2.1 什么叫“功能对标”
浏览器版本要对齐 Blender 的数据语义、操作结果和文件可恢复性,不承诺使用 Three.js 后与 Eevee/Cycles 像素一致。
每个功能验收都要回答四个问题:
- 操作是否能在 Web UI 中完成?
- 操作后 Blender 数据是否正确?
- 刷新或重新打开后结果是否一致?
- 结果能否用 Three.js 稳定显示?
2.2 功能分级
| 级别 | 说明 | 交付定义 |
|---|---|---|
| P0 | 可用编辑器 | 能打开项目、查看场景、编辑对象/网格并保存 |
| P1 | Blender 核心工作流 | 建模、材质、动画、常用修改器、glTF/OBJ/STL/PLY |
| P2 | 高级工作流 | 骨骼约束、几何节点子集、雕刻、Grease Pencil、模拟 |
| P3 | 桌面级扩展 | Python、插件、VSE、合成、复杂物理和大型导入器 |
| 不对标 | 浏览器不适合的桌面能力 | 原生窗口、多屏、原生插件、GPU 专属 Cycles/OptiX |
2.3 功能对标矩阵
| 功能域 | Blender 参考模块 | 首个目标 | 后续目标 | Web 实现策略 |
|---|---|---|---|---|
| 项目/文件 | blenloader, windowmanager |
P0 | P1 | 内存读写 .blend,OPFS 自动保存 |
| Blender UI 工作区 | windowmanager, screen, editors, interface |
P0 Blender 风格壳 | P1 可拆分编辑器 | React 实现 Window/Screen/Workspace/Area/Region/Editor 等价协议;不移植 C++ WindowManager/GHOST |
| 场景/集合/Outliner | blenkernel, editors/space_outliner |
P0 | P1 | SceneIR + React 树 |
| 对象模式 | editors/object, blenkernel |
P0 | P1 | WASM 命令 + Three.js gizmo |
| 网格编辑 | bmesh, editors/mesh |
P0 基础 | P1 常用工具 | BMesh 求值,SceneDelta 更新 |
| 三角面简化/LOD | modifiers/intern/MOD_decimate.cc, bmesh/tools/bmesh_decimate_* |
P0 预览/导出 | P1 完整 Decimate + 多级 LOD | 复用 Blender Decimate 求值;Three.js 只选择和渲染已求值 LOD |
| 修改器 | modifiers |
P1 常用 | P2 扩展 | 先白名单编译和回归 |
| 视口 | draw, gpu, editors/space_view3d |
P0 | P1 | Three.js WebGL2;不走 Blender GPU |
| 材质 | nodes, blenkernel, imbuf |
P0 PBR 子集 | P1 节点子集 | Principled 到 Three.js 材质映射 |
| 动画 | animrig, editors/space_action |
P1 关键帧 | P2 FCurve/约束 | WASM 求值 + AnimationMixer |
| 对象父子/骨骼层级 | DNA_object_types.h, DNA_armature_types.h, depsgraph |
P0 父子/骨骼树 | P1 约束和重定父级 | 保留 Object、EditBone、Bone、PoseBone 四类语义,WASM 负责权威求值 |
| 骨骼/蒙皮 | animrig, ikplugin, modifiers/intern/MOD_armature.cc |
P1 播放 | P1 编辑、蒙皮、约束 | Armature modifier、权重和逆绑定矩阵进入 SceneIR;Three.js 使用 Skeleton/SkinnedMesh |
| 几何节点 | nodes, geometry, functions |
P1 只读显示 | P2 白名单 | 先烘焙/服务器求值,不承诺全量 |
| 雕刻/绘画 | sculpt_paint |
P2 | P3 | Web Pointer 高频采样 + WASM |
| Grease Pencil | grease_pencil, editors/grease_pencil |
P2 | P3 | 先导入/显示 |
| 导入导出 | source/blender/io |
P1 glTF/OBJ/STL/PLY | P2 FBX/USD/Alembic | Worker 中转换,Three.js 显示 |
| 合成/VSE | compositor, sequencer |
不纳入 P0 | P3 | 服务端或独立 Web 模块 |
| Python/插件 | python, scripts |
默认关闭 | P3 沙箱 | 白名单 API 或服务端执行 |
3. 统一完成定义
3.1 代码完成
- C++ 代码通过 Web 构建和至少一个原生构建。
- C ABI 有版本号、空指针检查、错误码和资源释放函数。
- TypeScript 协议有 schema 版本,并生成类型定义。
- 新增行为有最小单元测试和一个 golden 场景。
3.2 功能完成
- Chrome、Firefox、Safari 最近稳定版至少各通过一次冒烟测试。
- 单线程构建可工作;多线程不可用时有明确降级信息。
- 引擎异常不会使 React 页面失去保存能力。
- 所有变更有 revision,可撤销、可重做或明确标注不可撤销。
3.3 性能完成
参考桌面设备的初始预算:
| 指标 | P0 预算 | P1 预算 |
|---|---|---|
| 首次加载 WASM(缓存后) | 5 秒内可见空场景 | 8 秒内可见首个对象 |
| 100k 三角形视口 | 30 FPS 以上 | 45 FPS 以上 |
| 单次对象变换 | 100 ms 内完成 delta | 50 ms 内完成 delta |
| 自动保存 | 不阻塞交互 | 2 秒内完成常规快照 |
| 内存 | 512 MB 场景不崩溃 | 1 GB 场景可诊断降级 |
这些是工程预算,不是浏览器平台保证。每个预算必须在 tests/performance/web/ 中有可重复脚本。
4. 连续任务总览
| 阶段 | 任务范围 | 结果 |
|---|---|---|
| A 基线 | W-000~W-006 |
仓库、依赖、目标和 golden 文件固定 |
| B Web 壳 | W-010~W-019 |
React、Three.js、Blender 风格 Workspace/Area、Worker、OPFS 壳可运行 |
| C WASM 引擎 | W-020~W-029 |
最小 Blender WebEngine 可加载 |
| D 场景数据 | W-030~W-039 |
.blend -> SceneIR -> Three.js 闭环 |
| E 持久化 | W-040~W-047 |
保存、自动保存、恢复和导出 |
| F 视口 | W-050~W-058 |
选择、相机、变换、视图模式 |
| G 核心建模 | W-060~W-079 |
P0/P1 网格、对象编辑和三角面 LOD |
| H 材质动画 | W-080~W-099 |
P1 材质、纹理、层级、蒙皮、关键帧和播放 |
| I 导入导出 | W-100~W-105 |
常用 Web 格式闭环 |
| J 高级能力 | W-110~W-118 |
按优先级加入 P2,不阻塞 P1 |
| K 质量发布 | W-130~W-142 |
性能、安全、兼容性和发布包 |
4.1 任务卡统一格式
每个 W-* 是一个可独立合并、可独立回滚的工作包;如果一个任务预计超过 2~5 个工作日,必须在状态文件中继续拆成 W-xxx.a、W-xxx.b 等子任务,但不得跳过父任务验收。所有任务卡必须包含以下字段:
Task ID W-xxx(可选 .a/.b 子任务)
目标 一句话说明用户或工程结果
前置证据 前置任务 status=done、commit、协议版本和能力探测结果
变更范围 允许修改的目录/模块;禁止顺手重构无关代码
执行步骤 1..N,每一步都有输入、输出和失败处理
交付物 源码、schema、测试、golden、文档和构建产物
验证命令 lint/typecheck/build/unit/e2e/golden/performance 中适用项
验收标准 可观察结果、容差、性能预算和兼容性范围
回滚方案 如何恢复上一个 revision、缓存、数据库 migration 或 WASM 包
状态 todo -> in_progress -> done,失败只能为 blocked 并记录原因
任务关闭顺序固定为:
- 在独立分支或独立 commit 中完成变更,不修改未声明的目录。
- 运行任务卡中的验证命令,保存 stdout、版本、浏览器和 commit 到
docs/status/<task-id>.md。 - 生成或更新
tests/golden/<task-id>/manifest.json;没有视觉结果的协议任务至少要有结构化 JSON golden。 - 更新
web/protocol/schema-version和迁移说明;禁止无记录地改变字段含义。 - 注入一次失败路径(取消、超时、损坏输入、OOM、quota 或 Worker 重启中的适用项),确认回滚到上一 revision。
- 将状态改为
done,再解锁下一个任务;若验证失败,保持in_progress或转blocked,不得标记完成。
4.2 可连续执行的原子工作包
下表是执行者实际领取任务时使用的细分索引。每个原子工作包都必须完成对应的 W-* 任务和关闭协议;同一行内可以拆子任务,但不能跨越未完成的前置行。
| 顺序 | 原子工作包 | 对应 W 任务 | 先交付什么 | 完成后解锁 |
|---|---|---|---|---|
| A-01 | 固定源码、工具链和目录 | W-000 | baseline、构建目录 | A-02 |
| A-02 | 依赖、许可证和浏览器能力 | W-001、W-002 | dependency matrix、capability report | A-03 |
| A-03 | golden 文件和坐标协议 | W-003、W-005 | .blend manifest、坐标/颜色 contract |
A-04 |
| A-04 | 错误、进度、revision 和协议版本 | W-004 | error/progress schema、v1 | A-05 |
| A-05 | 任务状态、日志和验证 runner | W-006 | status 模板、schema/golden/task 检查器 | B-01 |
| B-01 | React 工程和基础状态层 | W-010、W-011 | 可构建 AppShell、WorkspaceStore 接口 | B-02 |
| B-02 | EngineClient、mock Worker 和请求生命周期 | W-012 | request/response、取消、重启测试 | B-03 |
| B-03 | Three.js 空视口和存储烟测 | W-013、W-014 | WebGL2 截图、IndexedDB/OPFS smoke | B-04 |
| B-04 | Playwright 启动和 Worker/存储冒烟 | W-015 | e2e smoke、trace、错误路径 | B-05 |
| B-05 | manifest、离线资源和基础壳门 | W-016、W-017 | 资源哈希校验、Web runtime gate | B-06 |
| B-06 | Blender UI 协议和默认工作区 | W-018、W-019 | WorkspaceIR、Area/Region/Editor 壳、UI golden | C-01 |
| C-01 | Emscripten 和 Web CMake | W-020、W-021 | 可复现 build_web/ 配置 |
C-02 |
| C-02 | 最小 web_engine 和运行参数 | W-022、W-023、W-024 | 单线程 WASM、内存统计 | C-03 |
| C-03 | C ABI、报告和 Worker 真引擎 | W-025、W-026、W-027 | web_engine_*、错误报告、真实 ready |
C-04 |
| C-04 | 原生/WASM 双端回归 | W-028、W-029 | 空场景双端摘要、引擎 gate | D-01 |
| D-01 | .blend 内存读取和 SceneIR schema |
W-030、W-031 | 稳定 ID、schema fixtures | D-02 |
| D-02 | 场景树、集合、MeshIR | W-032、W-033 | Outliner 数据、二进制 mesh buffer | D-03 |
| D-03 | 材质、图像、相机、灯光、动画 | W-034、W-035、W-036 | MaterialIR/ImageIR/AnimationIR | D-04 |
| D-04 | 完整快照、增量和 revision 冲突 | W-037、W-038、W-039 | snapshot/delta adapter、场景截图 | E-01 |
| E-01 | OPFS 文件和 IndexedDB schema | W-040、W-041 | 目录校验、migration test | E-02 |
| E-02 | 原子保存、快照和恢复 | W-042、W-043、W-044 | save transaction、autosave、replay | E-03 |
| E-03 | 导入导出 UI、缩略图和持久化门 | W-045、W-046、W-047 | ProjectBrowser、恢复 golden | F-01 |
| F-01 | SceneIR 到 Three.js 的增量适配 | W-050、W-051 | Object3D/BufferGeometry adapter | F-02 |
| F-02 | 相机、输入、选择和 Outliner | W-052、W-053 | selection/context golden | F-03 |
| F-03 | Gizmo、覆盖层和资源释放 | W-054、W-055、W-056 | preview/commit、overlay、dispose | F-04 |
| F-04 | RenderWorker 可选路径和视口门 | W-057、W-058 | 双渲染路径截图、viewport gate | G-01 |
| G-01 | 对象模式和 Edit Mode 上下文 | W-060、W-061 | primitive、父子、BMesh session | G-02 |
| G-02 | 选择、基础 Mesh 操作和工具 | W-062、W-063、W-064 | topology golden、preview cancel | G-03 |
| G-03 | UV/材质槽、修改器和 depsgraph | W-065、W-066、W-067 | modifier stack、evaluated mesh | G-04 |
| G-04 | 撤销、搜索和基础建模门 | W-068、W-069、W-070、W-071、W-072 | replay、F3、建模回归 | G-05 |
| G-05 | Decimate 协议、实现和属性保护 | W-073、W-074、W-075、W-076 | Blender WASM authoritative simplify | G-06 |
| G-06 | LOD 缓存、预算和简化门 | W-077、W-078、W-079 | OPFS/IndexedDB LOD、误差和性能 gate | H-01 |
| H-01 | 材质、纹理、灯光、关键帧和基础骨骼播放 | W-080、W-081、W-082、W-083、W-084、W-085、W-086、W-087 | PBR/Timeline/FCurve/SkinnedMesh golden | H-02 |
| H-02 | Object/Armature 层级协议和编辑 | W-088、W-089、W-090 | ObjectNodeIR、BoneIR、父子命令 | H-03 |
| H-03 | Pose、约束、蒙皮和依赖图 | W-091、W-092、W-093、W-094 | PoseIR、SkinIR、Skeleton adapter | H-04 |
| H-04 | Joint LOD、层级导出和回归门 | W-095、W-096、W-097、W-098、W-099 | joint error、hierarchy golden | I-01 |
| I-01 | GLB/glTF 和常用格式 | W-100、W-101、W-102 | importer/exporter、asset resolver | I-02 |
| I-02 | 打包、格式回归和导出门 | W-103、W-104、W-105 | manifest、往返报告 | K-01 |
| K-01 | 性能、流式加载和线程 | W-130、W-131、W-132 | 100k/1M benchmark、降级报告 | K-02 |
| K-02 | 故障注入、安全和跨浏览器 | W-133、W-134、W-135 | recovery/security/browser matrix | K-03 |
| K-03 | 发布资源、测试总线和候选版本 | W-136、W-137、W-138、W-139 | CI report、P0/P1 release candidate | K-04、J-01 |
| J-01(可选旁路) | P2 模块评审和实现 | W-110~W-118 | 选定的 Modifier/Armature/节点/雕刻等模块及独立 gate | 下一周期;不阻塞 K-04 |
| K-04 | 文档、监控和季度复盘 | W-140、W-141、W-142 | migration guide、错误 dashboard、scorecard | 发布或下一周期 |
每个工作包完成后,只允许沿“完成后解锁”列继续。需要并行时,必须在状态文件中声明共享资源、合并顺序和冲突处理;默认仍按表中顺序串行执行。
4.3 验证命令约定
W-006 必须先创建统一 runner;后续任务不得依赖开发者本地手工点击作为唯一验收。命令名称可以随工具链调整,但语义和输出文件不能改变:
# Web 工程
npm --prefix web run lint
npm --prefix web run typecheck
npm --prefix web test
npm --prefix web run test:e2e -- --project=chromium
# Blender 原生/WASM
cmake --build build_native --target web_engine_test
cmake --build build_web --target web_engine
ctest --test-dir build_native --output-on-failure
# 协议、golden 和任务状态
node tools/web/check-schema.mjs
node tools/web/run-golden.mjs --task W-xxx
node tools/web/check-task-status.mjs W-xxx
# 性能和故障注入
node tools/web/run-performance.mjs --scenario <name>
node tools/web/run-fault-injection.mjs --task W-xxx
每个任务至少执行一条适用的静态检查、一条单元/原生检查和一条浏览器或 golden 检查;纯文档任务也必须执行 schema/链接/结构检查。runner 不存在时,先把 runner 作为当前任务的 .a 子任务完成,再执行功能实现。
5. 阶段 A:基线固定
W-000 固定源码和版本
前置:无。
执行:
- 以
blender-5.2.0作为 Web 上游源码目录。 - 记录 commit、编译器、Emscripten、Node.js、npm、CMake 和 Ninja 版本。
- 新建
docs/decisions/000-baseline.md,记录不可随意变更的版本。 - 原生构建保持独立,Web 构建使用
build_web/。
交付物:版本清单、构建环境脚本、baseline 文档。
验收:原生 Blender 可以从干净 build 目录启动;Web 分支没有修改原生 build 目录。
W-001 建立依赖和许可证清单
前置:W-000。
执行:扫描 extern/、lib/、CMake ExternalProject,标注每个依赖的 Web 状态:保留、替换、关闭、待验证。单独记录 Blender GPL、Three.js、Emscripten runtime 和浏览器原生存储的来源;SQLite WASM 保持延期,不进入首期依赖。
交付物:docs/web/dependency-matrix.md、docs/web/third-party-notices.json、
docs/web/local-dependencies.md、tools/web/check-local-deps.sh。
验收:任何新增链接库都能在清单中找到来源、许可证和 Web 构建结论;
npm run check:local-deps 通过,浏览器源码和 dist/ 不包含 CDN/远程 ESM
运行时地址,Three.js/WebEngine 资源从项目本地 vendor/ 加载。
W-002 建立浏览器能力矩阵
前置:W-000。
执行:编写能力探测页面,检测 WebGL2、OffscreenCanvas、OPFS、SharedArrayBuffer、Web Worker、WebAssembly SIMD、WebAssembly threads 和存储配额。
交付物:web/app/src/platform/capabilities.ts、能力探测页、浏览器矩阵。
验收:缺少任何能力时显示对应的降级路径,而不是在运行中产生未捕获异常。
W-003 建立 golden 场景目录
前置:W-000。
执行:从 tests/files 选择最小测试文件并增加 Web 专用文件:
tests/files/web/empty.blend
tests/files/web/basic_scene.blend
tests/files/web/mesh_edit.blend
tests/files/web/material_animation.blend
tests/files/web/large_scene.blend
每个文件生成对象树、顶点数、材质数、动画帧范围和关键截图基线。
交付物:golden .blend、manifest.json、预期 SceneIR 摘要。
验收:原生 Blender Python 可以读取 manifest 并验证每个文件的摘要。
W-004 定义错误、进度和 revision 规范
前置:W-000。
执行:定义 ErrorReport、ProgressEvent、EngineRevision、CapabilityError 和 StorageError。规定所有长任务必须支持 started/progress/completed/failed/cancelled。
交付物:web/protocol/error.ts、web/protocol/progress.ts、协议版本 v1。
验收:任何 Worker 异常都能映射到稳定的错误码和用户可读信息。
W-005 规定数据坐标和颜色语义
前置:W-003。
执行:确定 Blender Z-up 到 Three.js Y-up 的转换位置;确定单位、线性颜色、sRGB 贴图、法线、切线、透明度、曝光和色调映射规则。所有转换只允许在 adapter 层发生一次。
交付物:docs/web/coordinate-color-contract.md、转换测试。
验收:立方体、相机、灯光、UV 和动画在原生截图与 Web 截图中方向和比例一致。
W-006 建立任务状态和日志模板
前置:W-000~W-005。
执行:创建 docs/status/、tests/golden/、tests/performance/web/,规定每个任务的状态文件格式:变更文件、命令、测试、剩余风险。
交付物:任务模板和状态检查脚本。
验收:CI 能发现缺少状态文件、协议版本或 golden manifest 的任务。
6. 阶段 B:Web 应用壳
W-010 创建 React 工程
前置:W-006。
执行:在仓库根目录创建 web/,使用 React + TypeScript + Vite(或项目已确定的等价工具),加入 ESLint、格式化、类型检查和路径别名。禁止将 Blender 源码复制进前端包。
交付物:web/app、package.json、锁文件、npm run build。
验收:空页面可以开发启动和生产构建,产物不包含 Blender WASM。
W-011 建立应用布局和状态层
前置:W-010。
执行:实现 AppShell、ViewportPanel、OutlinerPanel、InspectorPanel、TimelinePanel、StatusBar 的基础骨架,并预留 WorkspaceStore、AreaStore、UIContext 接口。状态分成 UI、View、Engine、Persistence、Workspace 五层,禁止在 React store 保存完整顶点数组。
交付物:React 组件树和状态接口。
验收:基础面板开关、当前工具和项目状态不会触发 Three.js 场景重建;后续 W-018/W-019 可以在不改引擎协议的情况下接入 Blender 风格布局。
W-012 建立 EngineClient 和 Worker 通信
前置:W-004、W-010。
执行:实现 EngineClient、请求 ID、超时、取消、transferable buffer、revision 校验和 Worker 重启。先用 mock engine 返回一个固定 SceneIR。
交付物:web/engine-client/、web/workers/engine.worker.ts、mock 测试。
验收:连续发送 1000 个命令不会乱序;Worker 崩溃后 UI 能显示错误并重新连接。
W-013 建立 Three.js 视口烟测
前置:W-010、W-012。
执行:创建 WebGL2 renderer、Scene、PerspectiveCamera、OrbitControls、网格、灯光和 resize 处理。加入 renderer.info 采样。
交付物:web/three-adapter/viewport.ts。
验收:桌面浏览器中可旋转、缩放、平移,Canvas 尺寸和 device pixel ratio 正确。
W-014 建立 StorageWorker 烟测
前置:W-004、W-010。
执行:实现 StorageClient 和 StorageWorker;使用 IndexedDB 写入/读取测试记录,探测 Worker 内 OPFS 能力;大文件走 OPFS,小元数据不引入额外数据库 WASM。
交付物:web/workers/storage.worker.ts、存储能力页。
验收:写入记录、刷新页面、重新读取记录成功;Worker 不阻塞 React。
W-015 建立 Playwright 冒烟测试
前置:W-010~W-014。
执行:加入 Chromium 测试:启动、能力探测、打开 mock scene、视口交互、Worker 错误、存储读写。后续再接 Firefox/WebKit。
交付物:web/tests/e2e/、CI 命令 npm run test:e2e。
验收:无浏览器 GUI 的 CI 环境可以运行并生成截图和 trace。
W-016 建立资源 manifest 和 WASM 占位
前置:W-010。
执行:定义 engine-manifest.json,包含版本、能力、WASM 文件名、哈希、内存模式和协议版本。先放占位模块,验证资源加载和错误提示。
交付物:manifest loader、缓存策略、离线 service worker(可选)。
验收:哈希不一致时拒绝加载并显示可诊断错误;manifest 版本不兼容时阻止启动。
W-017 完成 Web 壳里程碑
前置:W-015、W-016。
验收:React + Three.js + 两个 Worker + mock SceneIR 在无 Blender WASM 情况下可以完整运行,标记 Web 运行时子阶段 done;Blender 风格 UI 还必须通过 W-018/W-019。
W-018 定义 Blender 风格 UI 协议和上下文
前置:W-011、W-017。
执行:定义 ScreenIR、WorkspaceIR、AreaIR、RegionIR、EditorIR、UIContextIR、OperatorRegistry、KeymapProfile 和 WebWorkspaceState。协议至少包含 workspace id/name、editor type、area/region bounds、split tree、active area、mode、active object、selection、view layer、pinned data、header/toolbar/sidebar 状态和布局 revision。
交付物:web/protocol/ui-schema.ts、默认 Layout workspace、Modeling/Animation workspace 模板、布局迁移版本、UI 命令清单。
验收:React 可以只根据协议创建或恢复布局;Area split/join/resize/maximize、Editor 切换、Workspace 切换、Panel 折叠和 Context 更新都有版本化命令;布局变化不直接修改 Blender 场景数据。
W-019 实现 Blender 风格默认工作区和交互
前置:W-018、W-013、W-015。
执行:实现 Blender Layout 风格的 Topbar、Workspace tabs、3D Viewport、Outliner、Properties、Timeline、Editor Header、Toolbar、Sidebar/N-panel、Status Bar、F3 Operator Search、模式切换、Undo/Redo 和快捷键上下文。支持桌面端拖拽 Area 边界、split/join、最大化当前 Area;移动端提供可折叠抽屉,但复用同一 Editor/Operator/Context 协议。快捷键按“鼠标所在 Area -> Editor -> Mode -> 全局”顺序路由,避免面板抢占视口快捷键。
交付物:WorkspaceShell、AreaFrame、RegionFrame、EditorHost、KeymapManager、OperatorSearch、布局持久化和 UI golden 截图。
验收:默认布局与 Blender 的工作区组织一致;用户可在不刷新页面的情况下切换 Layout/Modeling/Animation、调整面板、切换 Editor、最大化视口、搜索并执行已注册的基础/UI 操作;刷新后布局、活动 Editor、模式和快捷键偏好可恢复;同一命令在正确 Context 下得到与 Blender 对标的 Engine revision。完整建模 OperatorRegistry 在 W-069 接入,不能把 W-019 的 mock 操作计为建模功能完成。
7. 阶段 C:Blender WASM 最小引擎
W-020 建立 Emscripten 工具链
前置:W-001、W-006。
执行:固定 emsdk 版本,编写 tools/web/emscripten-env.sh 和容器/CI 镜像。验证 C、C++、pthread、SIMD、WASMFS 的最小示例。
交付物:工具链脚本、CI 缓存、版本输出。
验收:新机器按 README 可重复生成同样的工具链版本和 SHA-256。
W-021 添加 Web CMake 平台
前置:W-020。
执行:添加 WITH_WEB、build_files/cmake/platform/web.cmake 和 Web 专用 feature checks。关闭 X11、Wayland、SDL window、Vulkan、Python、Cycles、OpenVDB、USD、FFmpeg 等首期依赖。
交付物:Web CMake 配置、build_web/CMakeCache.txt。
验收:配置阶段不查找桌面系统库,不修改原生平台选项。
W-022 建立最小 web_engine target
前置:W-021。
执行:只链接 blenlib、guardedalloc、makesdna、makesrna、blenloader、必要的 blenkernel 和 bmesh。不链接 creator、windowmanager、editors 和 Blender 桌面入口。
交付物:source/blender/web_engine/、CMake target。
验收:生成 .wasm 和 ES module glue;导出一个空的 web_engine_create/destroy。
W-023 处理 Emscripten 运行参数
前置:W-022。
执行:先生成单线程包,再增加 pthread 包。设置 MODULARIZE、EXPORT_ES6、ENVIRONMENT=web,worker、内存增长、WebGL2 仅用于 Three.js 以外的能力探测,不在 Blender WASM 内创建 GPU context。
交付物:engine.single.wasm、engine.pthread.wasm、构建参数记录。
验收:单线程包可在 EngineWorker 初始化;pthread 包在 COOP/COEP 页面初始化,否则明确降级。
W-024 固定内存和分配策略
前置:W-023。
执行:统计 Blender 启动、空场景、100k 三角形、500MB 贴图的内存峰值。为引擎 buffer、临时读文件、SceneIR 导出定义 allocator 和释放边界。
交付物:内存测量脚本、EngineMemoryStats 事件。
验收:连续打开/关闭 20 个项目后 WASM 堆无持续线性增长,失败时返回内存错误而不是崩溃页面。
W-025 建立 Web C ABI
前置:W-022、W-024。
执行:实现 web_engine_create、web_engine_open_blend、web_engine_apply_command、web_engine_get_scene_snapshot、web_engine_get_scene_delta、web_engine_save_blend、web_engine_free_buffer、web_engine_destroy。所有导出函数只使用 POD、指针和长度。
交付物:source/blender/web_api/、C 头文件、TS loader。
验收:错误输入、重复释放、空指针、超长 buffer 都有确定返回值;C ABI 由 smoke test 调用。
W-026 接入 Blender 报告系统
前置:W-025。
执行:把 Blender ReportList 转换为 Report[],保留级别、模块、消息和建议。禁止把 C++ 日志直接写成不可解析的 stdout。
交付物:report bridge、错误映射表。
验收:损坏 .blend、缺失数据块、超出内存等错误在 React 中可显示和复制。
W-027 在 Worker 中加载 WASM
前置:W-012、W-025。
执行:EngineWorker 加载 ES module、创建引擎、发送 ready/capabilities;实现 Worker 重启和未完成请求的失败回收。
交付物:真实 EngineClient 实现、初始化 progress。
验收:mock engine 替换为真实空引擎后,阶段 B 的全部冒烟测试仍通过。
W-028 建立原生/WASM 双端测试入口
前置:W-025。
执行:同一组命令在原生 web_engine_test 和浏览器 EngineWorker 执行,比较 report、revision 和 SceneIR 摘要。
交付物:tests/web_engine/、双端 runner。
验收:空场景、创建对象、保存 buffer 的摘要在原生和 Web 端一致。
W-029 完成最小引擎里程碑
前置:W-020~W-028。
验收:浏览器真实加载 Blender WASM,创建空场景,返回 revision 和错误报告,标记阶段 C done。
8. 阶段 D:场景数据和 SceneIR
当前执行状态(2026-08-06)
| 任务 | 状态 | 当前证据/下一步 |
|---|---|---|
| W-030 | done |
内存 .blend 读取、zstd/gzip、BHead/DNA、Worker openBlend 和保存烟测 |
| W-031 | done |
SceneIR v1、稳定 ID、坐标/矩阵校验;images/animations 字段已版本化 |
| W-032 | done |
Scene/Collection/Object、父子、可见/可选、local/world matrix 和动态 Outliner |
| W-033 | in_progress |
已导出 positions/normals/UV/color/triangle material slots/bounds;Worker transferable binary envelope 和 Three corner attributes 已闭环;evaluated、tangent、split-normal 仍待完成 |
| W-034 | in_progress |
Principled 默认输入、emission/alpha/IOR、Image Texture ID/MIME/sourcePath 和 warning 已导出;N-013 四节点整图 Main 写回/保存重开已闭环;其余节点求值、graph hash、完整颜色空间仍待完成 |
| W-035 | in_progress |
相机 sensor/shift/裁剪、灯光半径/锥角/区域参数、World 颜色已导出;精确投影/方向仍待完成 |
| W-036 | in_progress |
帧范围、legacy/layered Action、关键帧/约束已闭环;N-014 单对象 Action Clip 整栈 Main 写回、重开和 frame depsgraph 求值已通过,Drivers/Transition/Meta/完整 NLA 仍待完成 |
| W-037 | in_progress |
Worker 已将 positions/index/normal/UV/color 等编码为 validated transferable binary envelope;evaluated mesh 与大模型分块仍待完成 |
| W-038 | in_progress |
SceneDelta diff/apply、revision 冲突校验、原生 C ABI get_scene_delta 以及 setFrame/setObjectVisibility 最小命令路径已闭环;mesh-buffer/material range、拓扑 delta 和完整 command registry 仍待完成 |
| W-039 | in_progress |
basic_scene 已闭环;等待 W-033~W-038 的完整验收 |
| W-040 | in_progress |
OPFS 项目路径校验、projects/ 场景/资产/缩略图/tmp/cache/lod 目录和临时文件写入辅助已实现;跨浏览器 rename/crash recovery 仍待完成 |
| W-041 | in_progress |
IndexedDB schema v6 已包含 project/asset/snapshot/log/quarantine/LOD/Simulation manifest stores 并有逐版升级 E2E;旧版本回滚测试仍待完成 |
| W-042 | in_progress |
StorageWorker transferable save 已实现 OPFS tmp->replace 与 IndexedDB project revision/size metadata,并有 E2E 证据;hash/crash recovery/snapshot manifest 仍待完成 |
| W-043 | in_progress |
1.5 秒可取消 autosave 已接入 React dirty 状态并经 E2E 验证;命令数阈值、快照保留和大文件背压仍待完成 |
| W-044 | in_progress |
operation_log schema、payload/inversePayload 写入和 StorageClient 接口已实现并经 E2E 验证;replay、损坏隔离和 native command recovery 仍待完成 |
| W-050 | in_progress |
Three adapter 已写入 blenderId/revision 元数据并支持纯节点 delta 原地更新;选择、相机/灯光替换和 mesh range delta 仍待完成 |
| W-053 | in_progress |
Outliner 行选择已绑定 activeObjectId 并经键盘/浏览器验证;视口 raycast、多选、隐藏过滤和删除清理仍待完成 |
| W-052 | in_progress |
OrbitControls、resize 和 Timeline transport 已接入并有 E2E 证据;精确相机 basis、视图预设、触摸和快捷键仍待完成 |
| W-060 | in_progress |
原生/Worker 命令协议、revision delta 和 setFrame/setObjectVisibility 已有 smoke/E2E 证据;primitive、duplicate、delete、join、separate、apply transform、parent、collection move 仍待实现 |
| W-073 | in_progress |
SimplifyProfile、SimplifyResult、LODManifest、attributePolicy、SkinSimplifyPolicy 及三种模式参数校验已加入协议;WASM/Worker 已验证 revision、拓扑、属性缓冲和 SceneDelta,W-079 的 native Blender golden 与中间比率回归已通过,完整属性/蒙皮 parity 仍待完成 |
| W-074 | in_progress |
Blender BMesh Collapse/Unsubdivide/Dissolve 已封装为 web_engine_decimate_apply 并本地安装;64 位 .blend BHead 与同属 Mesh 的重复 Attribute 块已安全解析,npm run test:topology-collapse 覆盖开放四边面、开放 n-gon 和非流形 Collapse;legacy 数据仍待扩展 |
| W-075 | in_progress |
modifier UUID/type/name/enabled、常用参数、确定性 stack hash、setModifierEnabled、有界 native undo/redo 和 TS dependency graph 已实现;evaluateDepsgraph 已接入 Blender 5.2 headless loader/真实 Depsgraph,18 个 category 类型已有 evaluated golden;本地 OpenSubdiv/GMP、Curve 和受控 Geometry Nodes Transform 闭包已接通;源文件回写/持久化 undo 仍单独跟踪 |
| W-076 | in_progress |
闭合、开放和非流形网格均有 BMesh 回归;Reader 已导出四影响权重、stable joint ID、armature rest/pose/bind matrix 和 shape key;native source-triangle 权重合并/归一化与 shape-key 重建已由 smoke/Worker 覆盖,seam/sharp 与 Blender Armature 变形误差仍待实现 |
| W-077 | in_progress |
已实现 LOD cache/OPFS/IndexedDB/独立 WASM/Three.js 选择与刷新发现;未求值 modifier stack 会阻断 LOD,防止缓存错误 base mesh;姿态 skin joints、原生 weight remap 和 Blender golden 扩展仍待完成 |
| W-078 | in_progress |
预算四层聚合、GLB warning、本地纹理/skin/动画导出、packed-image 原始字节提取和 GLB JSON/BIN/SceneIR 语义再导入对比均已闭环;更广泛 Blender 特性 warning 仍单独扩展 |
| W-079 | in_progress |
Blender 5.2 deformation golden、真实 native Depsgraph evaluated mesh、packed image 与 GLB semantic round-trip 已有 E2E 证据;完整 Decimate 参数矩阵和性能基准仍待补齐 |
状态证据位于 docs/status/W-030.md~docs/status/W-039.md;未能读取属性层的 Mesh 必须保持 summary-only,不能伪装成完整几何。
W-030 从内存读取 .blend
前置:W-029、W-003。
执行:首期使用 Blender BLO_file_reader_uncompressed_from_memory、Blender header/BHead/DNA API 在 WASM 内从 ArrayBuffer 读取,不依赖浏览器文件系统;支持 none/gzip/zstd 输入,startup 空 SceneIR 和用户文件两条路径。
交付物:openBlend(ArrayBuffer)、load report、golden loader test。
验收:empty.blend、basic_scene.blend 可以加载,openBlend(ArrayBuffer) 通过 Worker transferable buffer 完成,损坏输入返回 BLEND_READ_FAILED,禁止把用户文件路径直接传给原生 POSIX API。
W-031 定义 SceneIR v1
前置:W-005、W-030。
执行:定义 nodes、collections、meshes、materials、images、cameras、lights、animations、units、coordinateSystem、revision;节点同时携带 localMatrix/worldMatrix、visible/selectable 和 transform。稳定 ID 使用 Blender ID 名称加确定性重复后缀,不使用数组下标或裸 WASM 指针。
交付物:web/protocol/scene-ir-v1.ts、C++ serializer、schema fixtures。
验收:同一个 .blend 多次加载产生稳定 ID;浏览器运行时校验 schema、坐标约定、矩阵和定长 tuple;协议不包含裸 WASM 指针。
W-032 导出场景树和集合
前置:W-031。
执行:遍历 Main、Scene、Collection、Object,解析集合链表和对象 data/parent 指针,输出 parent、children、visibility、selectability、active camera 和 local/world transform;视图层覆盖留到后续 depsgraph 任务。
交付物:SceneIR nodes/collections exporter、Outliner mock data。
验收:基础嵌套集合、链接对象、隐藏/不可选标志和多场景字段在 Outliner/SceneIR 中可表达;循环父级不会导致无限递归。
W-033 导出 MeshIR
前置:W-031、W-032。
执行:先导出原始 Mesh 的摘要计数并标记 geometryStatus=summary-only,随后接入 evaluated mesh 的 position、normal、tangent、uv、color、index、material slot、bounds、object ID;区分原始 mesh 和 depsgraph evaluated mesh,未完成时禁止 Three.js 伪装成源几何。
交付物:MeshIR exporter、二进制 buffer layout 文档。
验收:立方体、非三角面、负缩放、镜像法线、多个 material slot 的顶点和面数与原生 Blender 对照一致。
W-034 导出材质、贴图和颜色
前置:W-033。
执行:首期读取 Principled BSDF 可映射字段:base color、metallic、roughness、normal、emission、alpha、index of refraction。图片只输出 asset ID、mime、尺寸和 hash。
交付物:MaterialIR、ImageIR、asset request API。
验收:贴图不内嵌为 base64;缺图、色彩空间错误和不支持节点都有 warning。
W-035 导出相机和灯光
前置:W-032。
执行:输出 camera type、focal length、sensor、clip、orthographic scale、灯光类型、颜色、能量、半径/角度和 world settings。
交付物:CameraIR、LightIR、WorldIR。
验收:透视/正交相机、点光/区域光/太阳光在 Three.js adapter 中方向和比例正确。
W-036 导出动画和帧状态
前置:W-032、W-034。
执行:读取 frame range、current frame、object transforms、shape keys、material parameters 的关键帧;先不导出复杂 driver 和约束求值细节。
交付物:AnimationIR、frame evaluation API。
验收:在 1、10、20 帧获取的 transform 与原生 Blender 脚本结果一致。
W-037 实现场景完整快照
前置:W-032~W-036。
执行:实现 get_scene_snapshot,一次返回轻量 JSON 摘要和 transferable binary buffers;加入大小统计和分块发送。
交付物:完整 SceneIR snapshot、snapshot decoder。
验收:basic_scene.blend 可以在浏览器展示,UI 不因 JSON 序列化大顶点数组而卡顿。
W-038 实现场景增量
前置:W-037。
执行:定义 SceneDelta 类型:node transform、visibility、mesh buffer range、material update、animation frame、object add/remove。每个 delta 带 baseRevision 和 nextRevision。
交付物:delta generator、delta applier、revision conflict test。
验收:只移动一个对象时,未修改对象不产生 delta;过期 delta 被拒绝并触发 snapshot 请求。
W-039 完成场景数据里程碑
前置:W-030~W-038。
验收:.blend -> Blender WASM -> SceneIR -> Three.js 场景的加载闭环通过 golden 截图和摘要比较,标记阶段 D done。
9. 阶段 E:OPFS、IndexedDB 和文件闭环
W-040 固定 OPFS 目录布局
前置:W-014、W-039。
执行:实现 projects/<id>/scene.blend、snapshots/、assets/<sha256>、thumbs/、tmp/。所有写入先临时文件再替换。
交付物:web/storage/opfs-files.ts、路径校验。
验收:路径不能穿越项目根目录;并发写入不会覆盖已提交文件。
W-041 建立 IndexedDB schema 和 migration
前置:W-014。
执行:创建 project、asset、snapshot、operation_log、setting、migration object store。每次 schema 变更都有数字版本和迁移测试。
交付物:web/storage/migrations/、schema test。
验收:空库可初始化;旧版本库可升级;升级失败不破坏原数据库。
W-042 保存 .blend 原子事务
前置:W-040、W-041、W-037。
执行:引擎生成内存 buffer -> 写 .tmp -> hash/size 校验 -> 原子替换 -> IndexedDB 更新 revision。事务失败时保留上一个 manifest。
交付物:saveProject()、save report、crash recovery test。
验收:模拟断电/刷新/Worker 失败后能恢复最后一个完整 .blend。
W-043 自动保存和快照策略
前置:W-042。
执行:按命令数、时间和内存阈值触发 autosave;大操作完成后立即快照。限制保留数量,提供用户手动保留快照。
交付物:autosave scheduler、snapshot list UI。
验收:连续编辑时不阻塞视口;刷新后显示最近保存时间和恢复选项。
W-044 记录操作日志和恢复
前置:W-038、W-041。
执行:记录 operation、payload、inverse payload、revision、时间和用户会话。打开项目时从最新 .blend 快照继续应用未提交日志。
交付物:operation log writer/replayer、corrupt log test。
验收:恢复后的 SceneIR revision 和正常连续操作结果一致。
W-045 文件导入导出 UI
前置:W-042。
执行:实现 <input type=file>、拖放、下载 Blob、项目列表、删除项目、导出当前 .blend。首期不尝试写任意本地路径。
交付物:ProjectBrowser、ImportDialog、ExportDialog。
验收:用户能在没有服务器的情况下导入、保存、刷新、导出并重新打开项目。
W-046 缩略图和项目索引
前置:W-042、W-013。
执行:Three.js 渲染低分辨率缩略图,写入 WebP 到 OPFS,IndexedDB 存 hash、尺寸、revision。缩略图生成在 Worker 或 requestIdleCallback 中执行。
交付物:thumbnail service、项目卡片。
验收:项目列表不读取完整 .blend;缩略图过期时能重新生成。
W-047 完成持久化里程碑
前置:W-040~W-046。
验收:导入、修改、自动保存、刷新恢复、手动导出、快照回退全链路通过,标记阶段 E done。
10. 阶段 F:Three.js 视口和交互
W-050 SceneIR adapter
前置:W-039、W-013。
执行:实现 node/mesh/material/camera/light 的 create/update/remove;所有 Three.js 对象写入 userData.blenderId 和 userData.revision。
交付物:web/three-adapter/scene-adapter.ts。
验收:完整快照创建场景,任意 SceneDelta 只更新受影响对象。
W-051 坐标、单位和色彩回归
前置:W-005、W-050。
执行:实现坐标矩阵、单位缩放、法线变换、sRGB/Linear 纹理设置、曝光和 tone mapping。增加坐标基准物体场景。
交付物:adapter regression tests、截图对照。
验收:X/Y/Z 轴、相机朝向、UV 方向、负缩放和动画插值正确。
W-052 相机和输入系统
前置:W-050。
执行:实现 OrbitControls、视图切换、frame selected、home、正交/透视、滚轮、触摸和快捷键。输入事件只发送语义事件,不直接改引擎数据。
交付物:ViewportInput、CameraController。
验收:鼠标、触摸和键盘在 React 面板焦点变化后仍不会误操作场景。
W-053 选择和 Outliner 联动
前置:W-032、W-050、W-052。
执行:射线拾取 Object3D -> Blender ID;实现单选、多选、主动对象、隐藏对象过滤、Outliner 点击定位和高亮。
交付物:SelectionStore、RaycastPicker、Outliner binding。
验收:视口和 Outliner 的选择始终一致;删除对象后选择状态清理。
W-054 变换 gizmo
前置:W-053、W-012。
执行:使用 TransformControls 生成 preview/commit 两类命令;支持 global/local/normal orientation、pivot 和 snapping 的 P0 子集。
交付物:TransformTool、命令映射。
验收:拖动过程中 Three.js 预览平滑,释放后 Blender WASM 确认最终矩阵;取消拖动不产生持久日志。
W-055 视图模式和覆盖层
前置:W-050。
执行:实现 solid/PBR/wireframe/ x-ray、网格、轴、选中轮廓、法线、边线、统计、相机框和灯光可视化。明确 Three.js 与 Blender 视觉差异。
交付物:ViewportSettings、OverlayRenderer。
验收:切换显示模式不重新加载 .blend;Overlay 不污染对象材质。
W-056 对象生命周期和 GPU 释放
前置:W-050。
执行:统一 dispose Geometry、Material、Texture、RenderTarget;对象删除、场景切换、Worker 重启都触发清理。
交付物:ResourceRegistry、GPU memory stats。
验收:打开/关闭 20 个项目后 GPU geometry/texture 计数回到基线附近。
W-057 可选 RenderWorker
前置:W-052、W-055、W-056。
执行:只在主线程视口稳定后迁移 OffscreenCanvas;输入事件通过代理发送。没有 OffscreenCanvas 时自动使用主线程。
交付物:RenderWorker、input proxy、双路径测试。
验收:两种渲染路径生成相同 SceneIR 和基本截图;Worker 不访问 DOM。
W-058 完成视口里程碑
前置:W-050~W-057。
验收:P0 场景查看、选择、Outliner、相机、变换、显示模式、Blender 风格 Area/Editor 上下文和资源释放全部通过,标记阶段 F done。
11. 阶段 G:Blender 核心建模
W-060 对象模式命令
前置:W-054、W-038。
执行:实现 add primitive(cube、sphere、cylinder、plane)、duplicate、delete、join、separate、apply transform、parent、collection move、hide/show。
交付物:对象命令注册表、命令回放测试。
验收:每个命令可由 UI、命令日志和测试脚本三种方式调用,结果可保存到 .blend。
W-061 Mesh Edit 上下文
前置:W-033、W-060。
执行:建立 BMesh edit session、对象锁、选择模式(vertex/edge/face)、selection flush、局部更新和退出编辑模式提交。
交付物:MeshEditSession、selection protocol。
验收:进入/退出 Edit Mode 不丢选择;同一个 mesh 被多个对象引用时有明确的 single-user 规则。
W-062 基础选择工具
前置:W-061、W-053。
执行:实现 click、box、circle、lasso、select all/none/invert、connected、linked、loop/ring 的 P0/P1 子集。选择结果用 element ID 或 index buffer 表示。
交付物:MeshPicker、selection overlay、selection tests。
验收:选择高亮与 BMesh 选择集合一致;100k 三角形下选择不会复制完整 MeshIR。
W-063 基础 Mesh 操作
前置:W-061、W-062。
执行:实现 move/rotate/scale、merge by distance、delete vertices/edges/faces、dissolve、triangulate、recalculate normals、flip normals。
交付物:mesh operator registry、BMesh regression tests。
验收:每个操作与原生 Blender 在顶点数、面数、法线和边界框上相符。
W-064 Extrude、Inset、Bevel 和 Loop Cut
前置:W-063。
执行:按 Blender 操作语义拆成 preview 和 commit;先实现 region extrude、individual extrude、inset、bevel、loop cut,记录鼠标距离/数值参数而不是记录每帧顶点。
交付物:工具参数模型、交互工具、golden mesh fixtures。
验收:重复执行同一命令得到相同拓扑;取消预览不修改 revision。
W-065 UV、颜色和材质槽
前置:W-063、W-034。
执行:支持 UV layer 列表、基本 unwrap/ smart project 接口、UV 平移缩放旋转、vertex color、material slot 分配。复杂 UV 算法先在原生/WASM 中验证再开放 UI。
交付物:UV command API、MeshIR UV delta。
验收:导出 glTF 后 UV 和材质槽可由 Three.js 还原。
W-066 常用修改器白名单
前置:W-063、W-064。
执行:按顺序加入 Mirror、Array、Bevel、Solidify、Subdivision Surface、Weighted Normal、Triangulate、Decimate。每个修改器独立开关,并维护 evaluated mesh 与 original mesh。
交付物:modifier capability registry、每个修改器一组 golden 文件。
验收:修改器堆栈顺序改变会产生不同结果;不支持的修改器显示明确 warning,不静默丢失。
W-067 变换应用和依赖图刷新
前置:W-060~W-066。
执行:对象变换、父子关系、修改器参数变化后只刷新受影响 depsgraph 节点;实现 dirty flags 和 evaluation progress。
交付物:dependency update bridge、delta profiler。
验收:修改一个对象不会重算无关 collection;循环依赖被报告并保持旧状态。
W-068 命令式撤销/重做
前置:W-044、W-060~W-067。
执行:建立 command stack、preview transaction、commit transaction、undo/redo、save point。BMesh 大操作使用快照或二进制差异,避免逐顶点 SQL 记录。
交付物:UndoManager、replay tests。
验收:连续 100 次建模操作可撤销/重做;保存点、刷新恢复和重做栈语义一致。
W-069 编辑器工具搜索
前置:W-060~W-068。
执行:建立操作注册表,包含 id、名称、快捷键、上下文、参数 schema、能力级别和报告。React 提供 F3 风格搜索,但只显示当前能力可用命令。
交付物:OperatorRegistry、CommandSearch。
验收:同一个操作可从快捷键、按钮和搜索触发;禁用原因可解释。
W-070 P0 建模工作区
前置:W-058、W-060~W-069。
执行:组合 3D View、Outliner、Inspector、工具栏和状态栏;实现对象模式/Edit Mode 切换和基本快捷键。
交付物:可操作 P0 建模工作区。
验收:用户可以从空项目创建模型、进入编辑、修改、撤销、保存和重新打开。
W-071 建模一致性回归
前置:W-070。
执行:对每个核心操作,在原生 Blender 运行 Python/操作脚本生成摘要,在 Web 端回放同一命令,比较拓扑、边界框、材质槽和 revision。
交付物:tests/python/modeling/web_parity/、差异报告。
验收:已支持操作无未解释差异;差异被记录为已知限制或修复任务。
W-072 完成核心建模里程碑
前置:W-060~W-071。
验收:P0 + P1 核心对象/网格建模工作流可连续执行,标记基础建模子阶段 done;三角面简化和 LOD 还必须通过 W-073~W-079。
W-073 定义 Blender 三角面简化和 LOD 协议
前置:W-066、W-071、W-072。
执行:建立 SimplifyProfile、SimplifyResult 和 LODManifest,参数必须与 Blender Decimate Modifier 对齐:COLLAPSE 的 ratio/percent、vertex_group、权重因子和反选、triangulate、symmetry_axis/容差;UNSUBDIV 的 iterations;DISSOLVE/PLANAR 的 angle_limit、边界处理和 delimit(Normal、Material、Seam、Sharp、UV、All Boundaries)。明确 Blender 的 ratio 以三角形目标数量为语义;关闭 triangulate 时保留可保留的四边形,不把 Web 端索引数量误当作 Blender 面数。
交付物:协议 schema、参数取值范围、错误码、triangleBudget、maxGeometricError、screenSpaceError 和 sourceMeshRevision 字段。
验收:同一 profile 在原生 Blender、Blender WASM 和 Web UI 产生相同的模式、参数和目标计数;无效组合(例如缺失顶点组或不支持的属性保护)必须拒绝并说明原因。
W-074 编译并复用 Blender Decimate 实现
前置:W-020~W-029、W-073。
执行:在 Web 构建中加入 source/blender/modifiers/intern/MOD_decimate.cc、source/blender/bmesh/tools/bmesh_decimate_collapse.cc、bmesh_decimate_unsubdivide.cc、bmesh_decimate_dissolve.cc 及其依赖的 DNA/RNA 定义。通过 C ABI 暴露“设置参数 -> 依赖图求值 -> 读取 evaluated mesh”的窄接口,保持 modifier stack 顺序和原始 mesh 不变。
交付物:blender_decimate_apply() ABI、能力探测、原生/WASM 构建目标和最小内存释放接口。
验收:Three.js/TypeScript 不实现权威的主简化算法;Three.js 只消费 MeshIR/LODManifest。WASM 关闭或能力缺失时,UI 必须显示不可用,而不能偷偷使用不同算法改变模型。
W-075 实现三种模式和修改器堆栈求值
前置:W-074。
执行:实现 Collapse、Un-Subdivide、Planar/Dissolve 三种模式的预览、提交、撤销和重新求值;支持 ratio/iterations/angle、对称轴、三角化和 delimit 标记。记录 modifier UUID、stack index、输入/输出 mesh revision,区分 original mesh、evaluated mesh 和导出 mesh。
交付物:Decimate Inspector、预览事务、WASM 评估事件和差异报告。
验收:改变堆栈顺序会得到可解释的不同结果;应用/禁用简化只改变对应 evaluated 结果;取消预览不改变源数据和 revision。
W-076 属性、UV 和蒙皮安全简化
前置:W-075、W-039。
执行:在边折叠、非细分和溶解后验证 UV、顶点色、材质索引、法线、切线、seam、sharp、顶点组和 shape key。对带 Armature modifier 的网格保留顶点组到骨骼的映射,按 Blender 规则合并并归一化权重;最大影响骨骼数、权重阈值和无法保留的 shape key 必须是显式 profile,不能静默丢失。
交付物:属性保护矩阵、SkinSimplifyPolicy、失败原因和权重误差统计。
验收:简化前后材质边界、UV seam、sharp 边和骨骼变形误差均在 profile 阈值内;不满足阈值时保留原始 LOD 并报告失败。
W-077 多级 LOD 生成、缓存和视口选择
前置:W-075、W-076、W-040~W-047。
执行:生成原始、近景、中景、远景 LOD,缓存键为 {objectId, meshRevision, modifierStackHash, profileHash, poseOrRestState}。OPFS 保存 cache/lod/<key>.mesh,IndexedDB 保存 manifest、三角形数、顶点数、误差、包围盒、材质槽和 skin joints。Three.js 根据投影屏幕尺寸/距离选择 LOD,并在切换时保持对象变换、材质和骨骼姿态连续。
交付物:LODGenerator、IndexedDB migration、缓存淘汰策略、Three.js LOD adapter。
验收:源网格编辑或 modifier 变化会使旧缓存失效;刷新后可复用有效缓存;LOD 切换不会触发全场景重建或明显跳变。
W-078 轻量化预算和导出策略
前置:W-077。
执行:为项目、collection、对象和 LOD 定义三角形/顶点/index/材质/纹理/显存预算;导出前生成轻量化报告。只有在 Blender 语义验证完成后才允许索引重排、量化、Meshopt/Draco 压缩或纹理压缩;GLB manifest 记录每级 ratio、误差、边界盒、材质和关节集合。
交付物:预算检查器、导出 warning、LODManifest 扩展和大模型分块导出。
验收:达到预算时报告实际节省量;未达到预算时给出具体对象/材质/纹理原因,不通过降低精度或删除权重来伪造成功。
W-079 三角面简化和轻量化里程碑
前置:W-073~W-078。
执行:建立 Blender 原生与 WASM 的 golden 摘要和截图测试:Collapse ratio 1.0/0.75/0.5/0.25、Un-Subdivide 0/2/4、Planar angle、各 delimit 标志、对称、顶点组和反选、UV/material/sharp seam、负缩放、带蒙皮网格、shape key、modifier stack 组合。加入 100k、1M 三角形性能和内存基准。
验收:三角形计数遵循 Blender 语义,几何误差和屏幕空间误差不超过 profile;源数据无变异,缓存可复用,目标设备内存预算可诊断;标记阶段 G done。该里程碑是 P0 轻量化和 P1 多级 LOD 的强制门槛。
W-079 连续执行队列(2026-08-06)
以下任务按顺序领取;每项都必须先通过前一项的离线命令,失败时保留 结构化错误和夹具,不得降级为 Three.js 侧的替代算法。
| 队列 | 前置 | 实现与交付物 | 验收 |
|---|---|---|---|
| W-079A-01 原生权重/shape key 重映射 | done(当前 triangle bridge) |
BMesh 输出顶点投影回源三角面,合并/截断/归一化四槽 joint influence,同步重建 shape key,并检查最大投影误差 | rigged fixture 的 native smoke 与浏览器 Worker 都验证 joint/bind/shape array;下一步补 Blender 骨骼变形误差 golden |
| W-079A-02 evaluated modifier graph | done |
evaluateDepsgraph 调用 Blender 5.2 headless BLO/DEG,返回最终顶点/三角形、源 Mesh ID、世界矩阵和 modifier 数;Worker/Client 和 rigged E2E 已接通;外部运行时资源仍结构化阻断 |
同一 .blend 的 evaluated Mesh 缓冲与 Blender golden/计数一致 |
| W-079A-03 GLB/Blender semantic round-trip | done |
本地 PNG buffer 已嵌入;严格解析 GLB JSON/BIN 并与 SceneIR 对比 image、skin/MAT4、morph 和 animation 语义 | 浏览器 round-trip 无 semantic mismatch |
| W-079A-04 复杂拓扑 Collapse | in_progress |
已覆盖开放 quad、开放 n-gon 与非流形共享边;继续扩展松散边、退化面、混合 manifold 峰值内存与原生 Blender 对比 | 每种合法输入不崩溃且输出索引、法线、属性范围有效;非法输入保持 summary-only 或结构化错误 |
| W-079A-05 golden/performance gate | W-079A-01~04 | 已加入 Blender 5.2 deformation error golden、packed image golden 和 GLB semantic round-trip;继续扩展 Collapse/Un-Subdivide/Dissolve、symmetry、UV/seam/sharp 与 100k/1M 基准 | 误差、计数和内存预算都有可重复基线,未解释差异阻止 W-079 完成 |
当前可连续执行的离线命令:npm run test:topology-collapse、
npm run test:collapse-ratios、npm run test:golden、
node tools/web/run-web-engine-smoke.mjs、cd web && npm run test:e2e。
12. 阶段 H:材质、纹理和动画
W-080 Principled 材质映射 (in_progress)
前置:W-034、W-050。
执行:建立 Blender node -> Three.js material 映射表,首期覆盖 base color、metallic、roughness、normal、emission、alpha、clearcoat 的可用子集。
交付物:MaterialAdapter、unsupported-node report。
验收:材质属性改变只更新材质,不重建 Geometry;颜色空间和透明排序正确。
状态记录:docs/status/W-080.md。tests/golden/W-080/animation-depsgraph.json 和
pose-constraint-depsgraph.json 是历史目录中的 N-003 frame/pose fixture,不计入
W-080 Principled 完成度。
W-081 纹理和资源生命周期
前置:W-040、W-080。
执行:从 OPFS 按 hash 加载 Blob/ImageBitmap,支持 PNG/JPEG/WebP/HDR 的能力探测;使用 mipmap、压缩和 dispose。
交付物:TextureStore、TextureAdapter。
验收:相同 hash 只加载一次;删除对象后无孤立 GPU 纹理。
W-082 灯光、世界和后处理
前置:W-035、W-080。
执行:实现环境光、方向光、点光、聚光、区域光的 Three.js 映射;加入阴影、雾、tone mapping 和基础后处理。记录与 Blender Eevee 的差异。
交付物:RenderSettings、lighting tests。
验收:灯光变化不触发 Blender 场景重载;低性能设备可以关闭阴影和后处理。
W-083 关键帧和播放
前置:W-036、W-050。
执行:实现 current frame、frame range、play/pause、loop、FPS、对象变换关键帧;Three.js 用 AnimationMixer 播放,WASM 负责保存和求值。
交付物:TimelineStore、AnimationAdapter。
验收:播放、拖动时间轴、设置关键帧和刷新恢复结果一致。
W-084 FCurve 和插值子集
前置:W-083。
执行:支持 constant、linear、bezier 插值,显示曲线摘要;暂不承诺所有 driver、噪波和自定义函数。
交付物:FCurveIR、curve editor P1 子集。
验收:关键帧在指定帧的数值与原生 Blender 误差小于约定阈值。
W-085 骨骼和蒙皮播放
前置:W-083。
执行:导出 armature hierarchy、rest pose、inverse bind matrix、weights;Three.js 使用 SkinnedMesh 和 AnimationMixer。
交付物:ArmatureIR、skin adapter、测试角色。
验收:导入角色动画播放,骨骼矩阵和顶点变形与 glTF/Blender 参考一致。
W-086 材质节点编辑器边界
前置:W-080。
执行:定义节点图 schema,只开放已映射节点;未映射节点显示 warning。节点图变更通过命令提交,不让 React 直接修改 Blender RNA 指针。
交付物:NodeGraphIR、NodeEditor P1 子集。
验收:支持节点的增删、连接、参数修改可保存和重新打开;不支持节点不造成静默黑材质。
W-087 完成材质动画基础里程碑
前置:W-080~W-086。
验收:基础 PBR、贴图、灯光、关键帧、骨骼播放和材质节点子集通过 golden 截图,标记材质动画子阶段 done;完整阶段 H 还必须通过 W-088~W-099。
W-088 固定 Blender 层级和关节数据模型
前置:W-033、W-067、W-085。
执行:协议不得把 Blender 的三套骨骼结构合并成一个数组:Edit Mode 的 EditBone 负责创建/编辑,Object.data.bones 的 Bone 保存 rest hierarchy,Object.pose.bones 的 PoseBone 保存姿态、动画和约束。对象层级单独保留 Object.parent、parent_type、parent_bone、parentinv、local/world matrix 和 collection 归属。
交付物:版本化 ObjectNodeIR、BoneIR、PoseBoneIR、SkinIR:
type ObjectNodeIR = {
id: string; parentId: string | null; parentType: string;
parentBoneId: string | null; parentInverse: number[];
localMatrix: number[]; worldMatrix: number[]; children: string[];
};
type BoneIR = {
id: string; name: string; parentId: string | null; connected: boolean;
useDeform: boolean; head: number[]; tail: number[]; roll: number;
matrixLocal: number[]; inheritFlags: number; collections: string[];
};
type PoseBoneIR = {
boneId: string; matrixBasis: number[]; poseMatrix: number[];
constraints: ConstraintIR[]; customProps: Record<string, unknown>;
};
type SkinIR = {
armatureId: string; vertexGroupToBone: Record<string, string>;
weights: SkinWeight[]; inverseBindMatrices: number[][]; maxInfluences: number;
};
验收:对象 UUID 和骨骼稳定 ID 是唯一引用;骨骼名称只用于 Blender FCurve/顶点组兼容,不能作为唯一主键;协议 schema 升级有迁移策略。
W-089 对象父子和父级操作
前置:W-060、W-067、W-088。
执行:实现 Object、Armature、Bone 等 parent_type;导出 parent inverse、父骨骼和 keep-world/clear-parent 语义。重定父级前后由 Blender depsgraph 计算矩阵,TypeScript 不自行重建 Blender 的父级公式;检测并拒绝循环父子关系。
交付物:parent/unparent/reparent 命令、矩阵差异报告、Outliner 层级更新事件。
验收:非均匀/负缩放、骨骼父级和集合实例场景下,keep transform 与 Blender 结果一致;撤销/重做不改变父级顺序。
W-090 导出和编辑骨架 Rest Hierarchy
前置:W-088、W-089。
执行:从 EditBone/Bone 导出 parent/children、connected、head/tail/roll、deform、inherit rotation/scale、bone collections 和显示属性。实现创建、重命名、连接/断开、删除、镜像和重定父级的编辑命令,并维护 Edit Mode 与 Object/Pose Mode 的边界。
交付物:Armature editor command registry、rest-pose golden 文件。
验收:连接骨骼的 child head 等于 parent tail;未连接骨骼保留独立 head;分支链、循环尝试和重命名后的 FCurve/顶点组引用均有测试。
W-091 PoseBone、FCurve 和约束求值
前置:W-083、W-084、W-090。
执行:导出 matrix_basis、pose matrix、可用的 rotation/scale mode、关键帧、drivers 状态和约束顺序。约束(至少 Copy Transforms/Copy Rotation/Limit Rotation/IK 白名单)在 Blender WASM 中按依赖顺序求值,Three.js 只接收结果矩阵和动画采样。
交付物:PoseIR、ConstraintIR、逐帧求值 API 和不支持约束 warning。
验收:rest pose、pose pose、动画帧和约束结果能区分;同一帧的骨骼矩阵与原生 Blender 在约定容差内一致。
W-092 Armature modifier 和蒙皮权重
前置:W-076、W-090、W-091。
执行:实现 Armature modifier 的对象引用、顶点组名称到骨骼 ID 的映射、归一化权重、inverse bind/rest 矩阵和 modifier stack 顺序。明确无权重顶点、非 deform 骨骼、最大影响数和权重裁剪策略;任何裁剪都记录在 profile 和导出 manifest。
交付物:SkinAdapter、weight validator、Armature modifier golden 测试。
验收:两个网格共享同一 armature 时只创建一个骨架实例;姿态改变只更新受影响的 SkinnedMesh;简化 LOD 不会破坏权重或逆绑定矩阵。
W-093 依赖图层级求值桥
前置:W-067、W-089~W-092。
执行:固定求值顺序:Object parent -> armature rest -> PoseBone -> constraints -> Armature deform -> modifiers -> SceneIR。为每个节点输出 dirty/revision/evaluation error,跨 Worker 发送拓扑排序后的 delta,避免 React 或 Three.js 递归推导源数据。
交付物:Depsgraph hierarchy bridge、evaluation trace、循环和缺失依赖错误码。
验收:只改变一根骨骼时不会重算无关 collection;父子循环、缺失 armature 和失效顶点组不会产生半更新场景。
W-094 Three.js 骨架和对象树适配器
前置:W-085、W-089~W-093。
执行:将 ObjectNodeIR 映射为 Three.js Object3D 树,将 BoneIR/PoseBoneIR/SkinIR 映射为 THREE.Bone、THREE.Skeleton、THREE.SkinnedMesh;坐标系转换只在适配边界执行一次。选择、Outliner、gizmo 使用稳定 ID,不直接用数组下标。
交付物:HierarchyAdapter、SkeletonAdapter、骨骼选择和姿态显示。
验收:父子矩阵、骨骼姿态、蒙皮顶点、隐藏/显示和选择状态在刷新和 LOD 切换后保持一致。
W-095 关节轻量化和骨骼 LOD
前置:W-078、W-092、W-094。
执行:将关节裁剪独立于三角面简化处理。只有当权重合并、动画姿态和屏幕空间误差均低于阈值时,才允许生成 joint LOD;保留根骨、约束引用、动画关键关节和必需 deform 骨骼,记录 joint remap、误差和逆绑定更新。原始 armature 数据永不被破坏。
交付物:JointLODProfile、joint palette 优化器、骨骼误差报告。
验收:不能因为减少 GPU joint palette 而丢失 Blender 约束或动画语义;无法满足误差阈值时回退到完整骨架。
W-096 层级和蒙皮导入导出
前置:W-090~W-095。
执行:实现 glTF nodes/scenes/skins/joints/animations 与 Blender Object/Bone/PoseBone 的双向映射,保留 Blender 名称、稳定 ID、父级顺序、inverse bind、权重和动画通道。对 OBJ/STL 等无骨骼格式明确不生成虚假层级。
交付物:层级导入导出器、joint order validator、往返差异报告。
验收:层级映射可以无损写入版本化导出 IR,joint order、绑定姿态、关键帧通道和材质对象引用均有校验;实际 GLB 文件往返在 W-100~W-105 完成,导出 warning 必须指出 glTF 无法表达的 Blender 特性。
W-097 层级编辑 golden 测试
前置:W-089~W-096。
执行:建立对象父子类型(OBJECT、ARMATURE、BONE 等)、connected/unconnected 骨骼、分支链、非均匀/负缩放、inherit flags、约束、两个网格共享 armature、keep-world 重定父级、动画和缺失权重样例。比较原生 Blender 的 hierarchy/pose/skin 摘要、顶点误差和截图。
交付物:tests/golden/hierarchy/、tests/python/rigging/web_parity/、跨浏览器截图基线。
验收:无未解释的父级、矩阵、骨骼顺序、权重或动画差异;失败用结构化 diff 定位到 object/bone/pose/skin 字段。
W-098 完成骨骼层级 P0/P1 里程碑
前置:W-088~W-097。
验收:P0 对象父子和骨骼树可创建、编辑、保存、恢复;P1 蒙皮、姿态播放、基础约束和导出映射契约可连续执行,标记骨骼层级子阶段 done。实际 GLB 往返由 W-100~W-105 验收;不得以“只在 Three.js 中显示骨架”作为完成标准。
W-099 材质、动画、层级综合回归
前置:W-087、W-098。
执行:将材质、动画、对象层级、蒙皮和三角面 LOD 放入同一批 golden 场景,验证修改 modifier、重定父级、改变姿态、切换 LOD、保存和导出 manifest 输入后的 revision/缓存失效关系。
交付物:综合回归矩阵、性能预算更新和发布阻断清单。
验收:阶段 H 的所有前置能力在同一场景中可连续使用;任何简化、关节裁剪或导出降级都在 UI、manifest 和日志中可追踪,标记阶段 H done。
13. 阶段 I:导入导出
W-100 glTF/GLB
前置:W-079、W-099。
执行:优先支持 GLB 读写和 Draco/Meshopt/KTX2 能力探测;导入后转为 SceneIR,导出时保留对象层级、材质、相机、灯光和动画。
交付物:glTF Worker、导入导出命令、golden glTF。
验收:Blender -> Web -> GLB -> Three.js 和 Web -> GLB -> Blender 往返不丢 P1 数据。
W-101 OBJ/STL/PLY
前置:W-063、W-100。
执行:实现 Worker 内导入,统一转 MeshIR;明确 OBJ 材质、STL 单位、PLY 属性的限制。
交付物:格式能力表、解析错误报告。
验收:常见模型可以导入、显示、编辑基础网格并导出;损坏文件不崩溃。
W-102 图像和环境资源
前置:W-081。
执行:支持项目资源 hash、相对路径替换、缺失资源列表和重新绑定。导入项目不允许访问任意本地路径。
交付物:AssetResolver、missing-assets UI。
验收:资源路径跨浏览器和刷新后仍可解析;缺失资源可人工修复。
W-103 导出打包
前置:W-100~W-102。
执行:导出 GLB 单文件和 zip 资源包;生成 manifest、版本、单位、坐标和警告列表。
交付物:ExportJob、download package。
验收:导出包在独立新标签页和桌面 Blender 中可验证。
W-104 格式回归矩阵
前置:W-100~W-103。
执行:每种格式建立模型、材质、动画、缺失资源、超大文件和损坏文件样例;记录支持级别和已知差异。
交付物:docs/web/io-compatibility.md、自动化矩阵。
验收:发布前不再使用“支持全部格式”这样的无依据表述。
W-105 完成导入导出里程碑
前置:W-100~W-104。
验收:P1 Web 格式闭环完成,标记阶段 I done。
14. 阶段 J:P2 高级能力
P2 按用户需求逐项启用,不得让单个高级模块阻塞 P0/P1 发布。每个模块必须先有能力探测和降级行为。
W-110 Modifier 扩展
前置:W-079。
执行:按使用量加入 Cast、Curve、Lattice、Shrinkwrap、Remesh、Multires、Geometry Nodes modifier。Curve、Lattice、Shrinkwrap 和 Geometry Nodes 的首个 Transform Geometry 闭包已有 native golden;其余类型及 Geometry Nodes 扩展继续按独立 CMake 依赖闭包和 golden 小批接入。
验收:未启用的 modifier 在 Inspector 中显示“不可用”及原因,不改变原始对象。
W-111 Armature 编辑和约束
前置:W-085、W-098。
执行:加入骨骼创建、parent、pose、IK/Copy Rotation/Limit Rotation 的白名单;约束求值在 Blender WASM,Three.js 只显示结果。
验收:标准测试角色可完成 pose、关键帧和重新打开恢复。
W-112 Geometry Nodes 策略
前置:W-067、W-079。
执行:首个原生白名单闭包已经实现:读取保存的节点树并求值 Group Input -> Transform Geometry -> Group Output,使用 Blender mesh transform 并与桌面 golden 精确比较。下一步按节点类别扩展字段、实例、拓扑节点和完整 lazy-function 依赖;simulation zone/bake data 当前显式阻断。复杂节点继续使用离线 Blender 求值后返回 mesh cache 的降级路径。
验收:不支持节点有可解释的 fallback;不会将未知节点错误当作空几何。
W-113 Sculpt/Paint 最小闭环
前置:W-062、W-063、W-056。
执行:实现 pointer pressure、stroke buffer、基础 Draw/Smooth/Grab、动态网格或多分辨率策略;高频笔刷数据使用 transferable/SAB,不经 React state。
验收:压力数据正确、撤销单笔操作、长笔刷操作不会造成页面卡死。
W-114 Grease Pencil 导入显示
前置:W-034、W-050。
执行:先读取笔画、层、帧、颜色并用 Three.js Line/Tube 或自定义 BufferGeometry 显示;编辑工具作为后续任务。
验收:测试 .blend 中 Grease Pencil 内容可打开和播放,缺失能力有 warning。
W-115 Physics/Simulation 边界
前置:W-067。
执行:明确刚体、布料、流体、粒子是否浏览器求值;优先采用缓存结果导入和服务器计算,不将未移植模拟当作 P1 能力。
验收:UI 能展示缓存状态、计算进度、取消和失败原因。
W-116 Compositor/VSE 边界
前置:W-082、W-100。
执行:首期只支持视口后处理和动画预览;完整合成、视频剪辑和音频交给服务端 Blender 或独立模块。
验收:产品文档和 UI 明确标注能力,不出现空白渲染或无提示失败。
W-117 Python 安全边界
前置:W-079。
执行:默认关闭 .blend Python 自动执行;实现脚本白名单、资源访问限制、超时和内存上限。任意 Python 作为服务端沙箱任务,不在默认页面执行。
验收:恶意脚本、路径穿越、无限循环和网络访问测试均被阻止或隔离。
W-118 完成 P2 评审
前置:需要发布 P2 的具体模块完成。
执行:对每个 P2 模块评估包体积、内存、浏览器兼容性、维护成本和使用量;未达到收益/成本阈值的模块保持服务端方案。
验收:每个启用模块有单独负责人、golden 文件、性能预算和降级方案。
15. 阶段 K:质量、性能和发布
W-130 性能基准
前置:W-058、W-079、W-099。
执行:建立空场景、100k、1M 三角形、1000 对象、4K 贴图、动画和大修改器堆栈基准。记录加载、解析、SceneIR、GPU、保存和内存峰值。
交付物:性能 dashboard、历史趋势。
验收:每次合并能比较基线;回归超过预算自动标红。
W-131 大场景和流式加载
前置:W-130。
执行:按 collection/object 分块发送 SceneIR,先加载相机和低模,再加载高模和贴图;实现取消、优先级和缓存淘汰。
验收:大场景首屏可交互,取消加载不会留下半初始化 GPU 资源。
W-132 多线程和 OffscreenCanvas
前置:W-057、W-130。
执行:在跨源隔离部署中启用 pthread/SharedArrayBuffer;比较单线程、EngineWorker、RenderWorker 的吞吐和交互延迟。
验收:线程池失败自动退回单线程;不允许主线程同步等待 WASM。
W-133 崩溃恢复和错误注入
前置:W-042、W-044、W-130。
执行:注入 WASM OOM、Worker terminate、OPFS quota、损坏 .blend、中途断网、IndexedDB 事务失败。
验收:所有错误都有恢复/导出路径,最近完整快照不被破坏。
W-134 安全审计
前置:W-117、W-132。
执行:检查 CSP、COOP/COEP/CORP、Worker 来源、文件类型、压缩炸弹、脚本执行、OPFS 路径、日志脱敏和供应链哈希。
交付物:安全清单、威胁模型、发布前修复列表。
验收:高风险问题全部关闭或有书面接受;未授权脚本不能访问文件和网络。
W-135 跨浏览器回归
前置:W-130~W-134。
执行:Chromium、Firefox、WebKit 测试 P0/P1 场景、存储、WebGL2、线程降级、导入导出和截图差异。
验收:支持矩阵中的每个组合有结果;不支持的组合有明确阻断页。
W-136 发布资源和缓存
前置:W-016、W-135。
执行:生成单线程/多线程 WASM、manifest、license、source notice、brotli/gzip 资源;配置 immutable hash cache 和回滚版本。
验收:清空缓存后可完整加载;旧项目能被兼容版本打开或给出迁移提示。
W-137 回归测试总线
前置:W-071、W-104、W-135。
执行:统一运行 C++ 单测、Blender Python 对照、浏览器 Playwright、golden screenshot、性能和 fuzz 测试。
交付物:tools/web/run-all-tests.ts、CI pipeline。
验收:一次命令能生成 HTML/JSON 报告,并关联任务 ID、commit 和协议版本。
W-138 P0 发布候选
前置:W-047、W-058、W-079、W-137。
发布范围:项目打开/保存、场景树、对象变换、基础网格编辑、Three.js 视口、OPFS 恢复、基础材质和导出。
验收:P0 完成定义全部通过;生成 release candidate,不把 P1/P2 未完成项混入承诺。
W-139 P1 发布候选
前置:W-099、W-105、W-137。
发布范围:常用修改器、PBR/纹理、关键帧/骨骼播放、glTF/OBJ/STL/PLY、操作日志和性能优化。
验收:P1 功能矩阵全部有实现或明确降级;golden 场景往返测试通过。
W-140 发布说明和迁移指南
前置:W-138 或 W-139。
执行:写清支持的 Blender 版本、文件兼容范围、浏览器要求、Three.js 渲染差异、未支持功能、隐私和本地存储清理方式。
交付物:用户文档、开发者文档、已知问题列表。
验收:没有“完全兼容 Blender”这类无法由测试证明的表述。
W-141 发布后监控
前置:W-138。
执行:收集匿名能力、WASM 加载失败、内存错误、保存失败、格式失败和性能摘要;不上传用户模型和贴图,除非明确授权。
交付物:错误码 dashboard、回滚手册、支持流程。
验收:线上问题可以根据错误码、浏览器、WASM 版本和协议版本复现。
W-142 功能对标季度复盘
前置:每个发布版本。
执行:根据 Blender 上游变化、用户操作频率、失败数据和维护成本更新矩阵;新的功能必须先进入 P2 评审,不直接破坏 P0/P1 协议。
交付物:季度 scorecard、下一周期任务队列。
验收:每个功能有状态、负责人、测试和明确的继续/暂停/移除决策。
16. 推荐执行顺序
实际执行时使用下面的连续链,不要跳到高级功能:
W-000~W-006
-> W-010~W-019
-> W-020~W-029
-> W-030~W-039
-> W-040~W-047
-> W-050~W-058
-> W-060~W-079
-> W-080~W-099
-> W-100~W-105
-> W-130~W-142
只有 P1 发布候选完成后,才从 W-110~W-118 选择 P2 功能。每个阶段结束都必须产出一个可运行版本,而不是等待全部功能完成后再第一次运行浏览器版本。
17. 首个可执行 Sprint
如果现在开始实施,第一轮只做以下任务:
A-01 -> A-02 -> A-03 -> A-04 -> A-05
-> B-01 -> B-02 -> B-03 -> B-04 -> B-05 -> B-06
下面的 W 任务是这条链的具体执行卡:
W-000:固定 Blender 5.2、Emscripten、Node、CMake、Ninja 版本。W-001、W-002:完成依赖/许可证清单和浏览器能力矩阵。W-003、W-005:准备 golden.blend和坐标/颜色 contract。W-004:冻结错误、进度、revision 和协议 v1。W-006:创建状态模板、schema/golden/task 验证 runner。W-010、W-011:创建 React 工程、基础 AppShell 和五层状态接口。W-012:接入 mock EngineWorker、请求生命周期和重启测试。W-013、W-014:完成 Three.js WebGL2 视口和 IndexedDB + OPFS 烟测。W-015:加入 Playwright 启动、视口、Worker 错误和存储冒烟测试。W-016、W-017:完成 manifest、离线资源和 Web runtime gate。W-018、W-019:冻结 Blender 风格 UI 协议,实现默认 Layout、Area split/join、Editor 切换、F3 搜索、快捷键上下文和布局恢复测试。
第一轮禁止加入 Python、Cycles、Blender C++ 桌面窗口后端、几何节点、雕刻或复杂导入器;但必须完成 Blender 风格的 React UI 壳,证明“React + Three.js + Blender 风格 Workspace + Worker + OPFS/IndexedDB”这条浏览器基础链路稳定。
18. Blender 语义参考和源码锚点
三角面简化和层级/关节实现以 Blender 官方文档和上游源码为准;本计划中的协议字段、golden 摘要和验收差异必须能回溯到以下锚点:
- Blender Decimate Modifier:Collapse、Un-Subdivide、Planar/Dissolve、ratio、iterations、angle、vertex group、symmetry、triangulate 和 delimit 语义。
- Blender Armature Structure:骨骼链、父子关系、connected/unconnected 语义。
- Blender Armature Parenting:骨骼父级、连接和重定父级操作。
- Blender Armature Skinning Introduction:对象/骨骼父子与 Armature modifier/权重蒙皮的区别。
- Blender Workspaces:工作区标签、布局切换和持久化语义。
- Blender Areas:Area 的编辑器容器、调整大小、拆分、合并和最大化行为。
- Blender Tabs and Panels:Header、Tabs、Panel 的折叠和上下文组织。
- Blender Outliner:对象树、集合、可见性、选择和父子管理。
blender-5.2.0/source/blender/modifiers/intern/MOD_decimate.cc:Decimate modifier 到 BMesh Collapse/Un-Subdivide/Dissolve 的调用入口。blender-5.2.0/source/blender/bmesh/tools/bmesh_decimate_collapse.cc、bmesh_decimate_unsubdivide.cc、bmesh_decimate_dissolve.cc:三种简化算法实现。blender-5.2.0/source/blender/makesdna/DNA_modifier_types.h、makesrna/intern/rna_modifier.cc:Decimate 参数、标志和 RNA 属性。blender-5.2.0/source/blender/makesdna/DNA_object_types.h、DNA_armature_types.h:对象父级、Bone 和 Armature 数据结构。blender-5.2.0/doc/python_api/rst/info_gotchas_armatures_and_bones.rst:EditBone、Bone、PoseBone 三套骨骼结构的边界。