chore: checkpoint web Blender feature-gap work, docs and tests
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

- update native web_engine sources and rebuilt wasm artifacts
- add task cards, status notes and tooling scripts
- add web e2e specs, tutorial UI sources and tutorial assets
- sync golden task manifests and audit records

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
mes123456
2026-11-11 10:46:55 +08:00
parent f3e21c6b98
commit d1e6b63d54
665 changed files with 59149 additions and 39194 deletions

View File

@@ -0,0 +1,154 @@
# Web Blender 三域全量对标桌面版实施计划
## Context
桌面 Blender 5.2 → Web/WASM 移植已形成可运行的编辑器骨架,但用户要求的三个核心建模域仍是有界子集:
- **创建模型**:仅 7 种网格基础体走原生 BMesh;Curve/Text/相机/灯光/Empty/骨架等 Add 入口在 `localOnly` 下被禁用;Surface/Metaball/Volume/GP/Lattice/Point Cloud 等整类缺失。
- **模型化**:仅 12 个网格操作,UI 参数固定;Knife/Rip/Spin/Symmetrize/Poke/Grid Fill/Shade Smooth 等缺失;元素选择仍是 React 本地状态;Web 修改器栈无 Apply。
- **模型层级**:父子/集合创建/移动/重命名/可见性已有原生 Main 路径;缺集合嵌套拖拽、删除、active collection、排序、per-ViewLayer 可见性、collection instance、bone/vertex parent、场景切换。
本计划把这三大域按「全量对标桌面 Blender」分阶段补齐。用户已确认:全量对标、沿用现有 WBV2 队列、全部对象类型、Edit Mode + 修改器 + 对象工具、桌面式 UI 全量对标、采用**通用 operator 通道**。
关键复用资产:`web_blender.desktop_operator_catalog/schema/desktop_operator`(`blender-5.2.0/source/blender/web_engine/web_engine_python_bootstrap.py:105-521`)与 `gpuUIInvoke` 原生窗口上下文(`web_engine_gpu_ui.cpp:1483-1523`)已具备属性 schema、选区上下文、modal 所有权、取消/撤销。现有 Add 菜单的 Curve/Text/相机/灯光本就指向这条通道,只是被 `localOnly` 开关挡住。
## 基线(源码派生,规划量化口径)
`tests/golden/WBV2/dynamic-inventory.json`(3,811 units,1,025 VERIFIED / 2,786 unverified):
| 域 | 源码单元 | 已验证 | 未验证 |
|---|---|---|---|
| 创建 + 对象操作 `OBJECT_OT_` | 215(object 目录 235) | 15 | 200 |
| 集合操作 `COLLECTION_OT_` | 12 | 0 | 12 |
| 模型化 `MESH_OT_` | 164 | 8 | 156 |
| Outliner `OUTLINER_OT_` | 73 | 0 | 73 |
| 修改器源 `MODIFIER` | 98 | — | — |
| RNA 属性(UI/属性面板相关) | 979 | — | — |
这些数字只是源码单元覆盖口径,不等于用户可见功能;完成判定必须绑定 capability、module manifest 与真实 Main mutation 证据。
`web/app/src/capabilities/blender-feature-route-catalog.json`(3,811 entries)当前路由分类:
| 单元族 | WEB_MAIN | SERVER_NATIVE | BROWSER_EQUIVALENT |
|---|---|---|---|
| `MESH_OT_` | 8 | 156 | 0 |
| `OBJECT_OT_` | 15 | 200 | 0 |
| `COLLECTION_OT_` | 0 | 12 | 0 |
| `OUTLINER_OT_` | 0 | 0 | 73 |
| `MODIFIER` | 96 | 0 | 2 |
完成口径:三域所有 `SERVER_NATIVE` 单元必须转为有证据的 `WEB_MAIN`;`OUTLINER_OT_` 的 73 个 `BROWSER_EQUIVALENT` 需重新裁决——要么改走原生 Main/operator 通道,要么以只读/纯 UI 语义给出明确证据,不能默认把浏览器近似当等价。
## 总体路线
**共享原语优先,一个模块覆盖一族操作符。** 不为单个 operator 建任务,也不为每个 operator 写专用 C++ 分支。
```text
通用 operator 通道(catalog / schema / invoke / context / undo)
-> 三个域的 module 能力层(capability + 命令契约 + 负例边界)
-> 桌面式 UI(Add/Edit/Object/Outliner 菜单、F3、右键、属性面板)
-> 每模块 manifest / unit 绑定 / status
```
### 现有共享实现(直接复用,不重造)
- **Operator Palette 已存在**:`web/app/src/app/App.tsx:380-530` 已实现路由搜索、`listLocalDesktopOperators`、`describeLocalDesktopOperator`、`chooseRoute`、`chooseOperator` 和属性表单;`gpuUIInvoke` 在 `WebEngineClient.ts:470`。
- **本地原生目录已覆盖全部注册 operator**:`WebEngineClient.ts:879-907` 的 `listLocalDesktopOperators` 直接查询 `bpy` 实时 WM registry,返回全部已注册操作符(route 标 `UNAVAILABLE`,由 `desktop_operator` 的 RNA/poll/EXEC_DEFAULT 决定可执行性),`describeLocalDesktopOperator` 读取实时 RNA schema。因此通用通道本身已覆盖 164/215/73 等操作符,主要工作是启用、菜单接线、逐族证据与缺失语义补齐。
- **原生目录与 schema**:`web_blender.desktop_operator_catalog` / `desktop_operator_schema` / `desktop_operator`(`web_engine_python_bootstrap.py:105-521`)。
- **路由目录**:`web/app/src/capabilities/blender-feature-route-catalog.json`(3,811 entries,按 `WEB_MAIN` / `SERVER_NATIVE` / `BROWSER_EQUIVALENT` 分类)。
- **Main 写回与重建**:`web_engine_api.cpp:1033-1105` 命令后写 .blend 并重建 SceneIR;undo push 在 `:4043-4047`。
- **Outliner 原生行**:`web_engine_main_state.cpp:10230-10279` 调 `outliner_build_tree`,前端 `App.tsx:1606-1903` 渲染。
- **能力矩阵契约**:`docs/BLENDER_WASM_CAPABILITY_MATRIX_TEMPLATE.json`(L0-L5、positive/negative/persistence/undoRedo/resource cases、evidence)。
三个域的工作重点是:把 `SERVER_NATIVE` 路由逐族转为有证据的 `WEB_MAIN`,把 Operator Palette 的能力接入真实菜单/快捷键/Outliner,而不是新建第二套执行器。
每个 module 任务必须交付:能力契约、原生 Main mutation、UI 接线、负例 no-mutation、undo/redo、save/reopen、Worker restart、module manifest 与 status;实现期结果标 `NOT_CLAIMED`。
## 阶段与模块
**阶段顺序理由**:先创建(一切对象的前提),再层级(创建落点、active collection、父子上下文与 Outliner 操作符,同时体量较小可快速验证通道),最后模型化(最大体量,依赖已统一的选择权威与对象上下文)。修改器与对象工具随模型化阶段推进。
### Phase 0 — OPERATOR_CHANNEL_FOUNDATION(前置,计入覆盖需带正例)
- 冻结三域 464 个 operator 单元(164 + 215 + 12 + 73)+ 98 个修改器源 + 相关 RNA 到 module/capability 的映射。
- 加固通用通道:catalog 分页、schema 深度/预算、`areaType`/`mode`/`selectedObjects`/`activeObject` 上下文、`baseRevision` 失效码、modal 取消与输入恢复。
- 代表正例:通过现有 Operator Palette 创建一个非 7 基础体对象(如 Curve Text 或 Monkey),验证 Main mutation、undo、save/reopen;同时验证 `baseRevision` 失效、错误 mode/area、modal 占用三类负例。
- 关键文件:`web_engine_python_bootstrap.py`、`web_engine_gpu_ui.cpp`、`web_engine_python.cpp`、`web/app/src/engine-client/WebEngineClient.ts`、`web/app/src/app/App.tsx:380-530`、`web/protocol/web-engine.ts`。
### Phase 1 — 创建模型全量
| Module | 覆盖 | 复用/接线 |
|---|---|---|
| `OBJECT_CREATE_MESH_PRIMITIVES` | 桌面 Mesh 全部基础体(含 Circle/Grid/Monkey)及参数(rotation/scale/align/enter_editmode) | 通用通道 + `bpy.ops.mesh.primitive_*_add`;保留 `createPrimitive` 作为快路径 |
| `OBJECT_CREATE_CURVE_SURFACE` | Bezier/NURBS/Circle/Path/Curve、Surface、Text 3D 对象 | 通道 + `editors/curve/curve_ops.cc` 注册表 |
| `OBJECT_CREATE_NONMESH` | Metaball、Volume、GP、Point Cloud、Hair Curves、Lattice | 通道 + 对应 `OBJECT_OT_*_add` |
| `OBJECT_CREATE_HELPERS` | Empty(全部显示类型)、Light(全部类型/参数)、Camera、Speaker、Light Probe、Effector | 通道;属性面板改为 schema 驱动 |
| `OBJECT_CREATE_GENERIC` | 通用 `OBJECT_OT_add` / `add_named`、Collection Instance、Edit Mode Add | 通道 + `object_add.cc` |
UI:`web/app/src/app/App.tsx:6881-6925` Add 菜单改为复用 Operator Palette 的 `chooseRoute`/`chooseOperator`(`:380-530`),移除 `localOnly` 禁用;F3(`:6560-6563`)与快捷条(`:7175`)同源;属性对话框由 `desktop_operator_schema` 生成。每类 Add 项在 `blender-feature-route-catalog.json` 中从 `SERVER_NATIVE` 转为 `WEB_MAIN` 并绑定证据。
### Phase 2 — 模型层级全量
| Module | 覆盖 | 缺口/接线 |
|---|---|---|
| `SCENE_HIERARCHY` | 集合嵌套/拖拽、删除集合、active collection、对象/集合排序、场景新建/切换/重命名、master collection 重命名 | 扩展 `core-scene-commands.ts` 构造器;`web_engine_main_state.cpp:17155-17319` BKE 路径 |
| `COLLECTION_VISIBILITY` | per-ViewLayer 眼/渲染开关、exclude/holdout/indirect/hide | 已有 `set_scene_collection_settings:22256`,补 Outliner UI |
| `PARENTING_TYPES` | Bone/Vertex parent、parent_type、inherit flags、保持变换 | `setParent` 扩展 + `object_relations.cc` 语义 |
| `COLLECTION_INSTANCE` | collection instance 数据、SceneIR、视口、Main 写回 | `scene-ir.ts:607-616` 扩展;`reader`/`viewport` 同步 |
| `OUTLINER_OPERATORS` | 73 个 `OUTLINER_OT_`(删除、重命名、排序、可见性、选择、拖放等) | 通用通道 + `space_outliner` 原生实现;`App.tsx:1606-1903` 接线 |
数据模型扩展:`SceneNodeIR`(`scene-ir.ts:40-57`)增加 parent_type/parent_bone/collection 成员;`SceneIR`(`:618-692`)增加 activeCollectionId;`SceneIR` 校验与 reader 同步。
### Phase 3 — 模型化全量
| Module | 覆盖 | 缺口/接线 |
|---|---|---|
| `MESH_SELECTION_AUTHORITY` | 点/边/面选择写回原生、选择历史、Select All/None/Invert/Linked/Similar | `selection-history.ts` 接入 `App.tsx`;原生 selection 上下文 |
| `MESH_EDIT_OPERATORS` | 164 个 `MESH_OT_`:Extrude/Inset/Bevel/Loop Cut/Knife/Rip/Spin/Symmetrize/Poke/Grid Fill/Unsubdivide/Merge by Distance/Shade Smooth/Flip Normals 等 | 通用通道 + `editors/mesh/` 注册表;现有 12 个 typed 命令保留为快路径 |
| `MESH_MODAL_TOOLS` | 交互式 Knife/Loop Cut/Bevel/Inset/Extrude/Spin 等模态操作 | `gpuUIInvoke` modal 路径(`web_engine_gpu_ui.cpp:1470-1530`),取消/输入恢复 |
| `OBJECT_MODELING_TOOLS` | 变换 pivot/orientation/snapping、duplicate/linked、join/separate、mirror/array、shade smooth/flat、apply transform | `App.tsx:1561-1591,6895,7175`;对象级 `OBJECT_OT_` |
| `MODIFIER_FULL` | 98 个修改器源、WITH_WEB 白名单扩展、Apply/Apply as Shape Key/copy-to-selected、schema 驱动参数 | `web_engine_main_state.cpp:12223-12254,7955-7974`;`editor-workflow.ts:516-517` |
| `UV_AND_ATTRIBUTES` | seam/sharp 标记、unwrap/pack/stitch 全量、属性域编辑 | 现有 `NativeUVEdit` 与 `uv-*` 协议扩展 |
### Phase 4 — 桌面式 UI 全量对标与收口
- `DESKTOP_MENU_KEYMAP_PARITY`:Add/Object/Select/Mesh/Vertex/Edge/Face/UV 菜单结构、快捷键、F3 操作符搜索、右键菜单、属性面板布局对齐桌面。
- 每个 module 的 UI 入口必须走同一能力目录(`web/app/src/capabilities/`),避免 App.tsx 内再造平行列表。
- 收口检查:三域所有映射 unit 有证据、无 unverified;负例边界稳定错误码;undo/save/reopen/restart 全链路;module manifest 与 capability matrix 一致。
## 实施批次规则(遵循 AGENTS.md)
- 每个 module 任务按小批次执行:单次读源码≤30 行、修改≤2 文件且增删≤10 行;批次间写 `continuationNotes`。
- 复用现有 `wbv2-implementation.service` / `run-wbv2-scheduler.mjs` 自动补缺;不手工推进 `nextTask`。
- 实现期只做增量编译(`cmake --build build_web_blender6 --target web_engine -j8` → `node tools/web/sync-web-engine-runtime.mjs`),不跑全量测试/回归/浏览器验收。
- 全部功能实现完成后进入用户验证;未验证结果如实记录,编译成功不等于功能完成。
- 新任务由现有队列生成器创建(`tools/web/generate-task-card.mjs` / scheduler),任务 ID 由队列分配;计划只定义 module/capability,不手写队列指针。
- 队列接入方式:把 module 记录加入 `tests/golden/WBV2/task-index.json` 指向的 source plan(字段含 `id`、`module.moduleId`、`module.sourceBacked: true`、`dependsOn`、`capabilities`、`reusedReceipts`),运行 `node tools/web/generate-task-index.mjs` 与 `node tools/web/generate-task-card.mjs --task <id>` 生成索引/任务卡;执行用 `node tools/web/run-wbv2-module-task.mjs --task <id> --write`。
- 源码单元绑定:模块完成时更新 `dynamic-inventory.json` 的 coverage、`blender-feature-route-catalog.json` 的 route/evidenceStatus,并在 module manifest 记录 `unitCount`、`verifiedUnits`、`sourceTreeSha256` 与本模块新增绑定。
## 关键风险与对策
1. **通用通道的上下文依赖**:`desktop_operator` 需要正确的 area/mode/selection;Web UI 无原生 area 时需映射(`areaType`),失败返回稳定错误码而不是静默降级。
2. **模态操作所有权**:原生 modal 期间 Web 输入必须让位;复用 `NATIVE_INVOKE_MODAL_OWNER_ACTIVE` 与 cancel/recovery 语义。
3. **选择系统割裂**:Web 本地选择与原生选择必须统一为 Main 权威,否则 Extrude/Knife 等操作对象错误;`MESH_SELECTION_AUTHORITY` 必须先于大规模操作符接线。
4. **修改器白名单**:`MOD_util.cc` WITH_WEB 与 98 个源之间存在差距;按 family 逐个打开并绑定负例,不一次性放开。
5. **Collection per-ViewLayer 语义**:桌面眼/渲染开关属于 LayerCollection,不是全局 Collection flag;需先扩展数据模型与 reader。
6. **场景切换与 Main 生命周期**:切换场景会影响 depsgraph/undo/Worker;复用现有 Main reset/reload 语义并加负例。
7. **linked 只读**:linked 集合/对象必须继续 fail closed,不允许通过通用通道绕过。
8. **UI 规模**:菜单/快捷键全量对齐容易与现有 Web 快捷操作冲突;建立单一 keymap 契约(`web/protocol/keyboard-contract.ts`)并逐项迁移。
9. **OCCT 约束**:三域移植以 Blender 原生 BMesh/BKE 为准;仓库内未检索到 OCCT 适配,若后续新增非 Blender 几何算法,按 AGENTS.md 统一到 OCCT WASM,不用 Three.js 计算。
## 验证与验收(全部功能实现后)
- 每个 module:正例 Main mutation、负例 no-mutation、undo/redo、save/reopen、Worker restart、Chromium 主线程与 OffscreenCanvas 视口。
- 三域汇总:inventory 映射 unit 全部有证据;module manifest 与 `docs/status/` 一致;未验证项为 0 才可声明该域对标完成。
- 用户验证:在 Chromium 中按桌面 Blender 操作路径实测创建、建模、层级三类工作流。
- 不以编译成功、单例通过、协议存在或覆盖率统计替代功能完成。
## 第一批可执行任务(建议)
1. `OPERATOR_CHANNEL_FOUNDATION`:通道加固 + 一个非网格对象的创建正例(Proof)。
2. `OBJECT_CREATE_MESH_PRIMITIVES`:补齐 Circle/Grid/Monkey 与基础体参数,Add 菜单去 `localOnly` 限制。
3. `OBJECT_CREATE_CURVE_SURFACE`:Bezier/NURBS/Circle/Text 3D 对象 + schema 属性。
4. `SCENE_HIERARCHY`:集合嵌套拖拽、删除、active collection、排序。
5. `MESH_SELECTION_AUTHORITY`:Web 选择写回原生,为后续 164 个网格操作符铺路。

View File

@@ -0,0 +1,57 @@
# Web Blender 三域用户验证清单
更新时间:2026-11-10
范围:创建模型 / 模型化 / 模型层级
验证环境:Chromium,本地 WASM 引擎(`localOnly`)
状态:全部条目 **NOT_CLAIMED**,仅作为用户验证路径清单,不是验收证据。
## 1. 创建模型
在 Object 模式打开“添加”菜单:
- 网格:立方体、平面、UV 球、棱角球、圆柱、锥体、环体、圆环(Circle)、栅格(Grid)、猴头(Monkey)。
- 曲线:贝塞尔、圆形、NURBS 曲线、NURBS 圆、路径。
- 曲面:6 种 NURBS Surface。
- 文本、骨架、空物体(普通轴/箭头/单箭头/圆/立方体/球/锥体)、相机、灯光(点/面/日光/聚光)。
- 非网格:融球(5 类型)、体积、晶格、蜡笔(空白/笔画/猴头/场景线稿/集合线稿)、点云、毛发曲线、随机毛发、扬声器、光照探针(3 类型)、力场(13 类型)。
- “更多对象…”打开 F3,可搜索通用 `object.add` / `add_named`。
- 编辑模式下“添加”子菜单可向当前网格加入基础体。
每条路径检查:对象出现在 Outliner/视口、撤销/重做、保存后重开仍存在。
## 2. 模型层级
- Outliner:对象行拖到对象行(Shift)设父级;拖到集合行移入集合(Ctrl 链接);集合行拖到集合行嵌套。
- Collection Properties(Properties 面板):
- 重命名、删除集合、删除层级、在本集合下新建子集合、设为活动集合、集合实例、上移/下移。
- 每视图层的排除/Holdout/仅间接/隐藏开关(作用在当前活动 View Layer)。
- 顶栏场景选择器切换场景;场景菜单新建/复制设置/删除场景、添加/删除视图层。
- 物体菜单:父级(原生物体/骨架/骨骼/骨骼相对/曲线)、清除父级(保持变换/清除逆矩阵)。
- 检查:层级在保存/重开后保持;循环父子或删除 master 应被拒绝。
## 3. 模型化
- 选择:视口选择模式(点/边/面);选择工具(全选/取消/反选/相连/相似/更多/更少/松散/非流形/随机/内部面/未分组/按轴/间隔/按边数)。
- 网格菜单:挤出/内插/倒角/细分/循环切割/合并/溶解/删除;扩展工具(Poke、Grid Fill、对称化、按距离合并、取消细分、着色、翻转法线、拆离、缝合线/锐边);更多网格(平滑、圆形化、凸包、清理、法线、UV 数据、顶点连接、线框等)。
- 模态工具:切割(K)、循环切割、倒角、内插面、挤出区域、投影切割(需要原生画布)。
- UV:展开(角度/共形/最小拉伸)、智能投影、打包/平均岛缩放、接缝转岛、减小拉伸。
- 修改器面板:添加/删除/上下移动/参数编辑;Apply、存为形态键、复制、复制到选中。
- 新增支持的修改器类型:Weighted Normal、Corrective Smooth、Laplacian Smooth、Mask、Normal Edit、Skin、UV Project、UV Warp、Warp、Data Transfer、WeightVG Edit/Mix/Proximity、Laplacian Deform、Particle Instance、Surface、Mesh Cache、Mesh Sequence Cache、Multires、Explode。
- 物体菜单:着色(平滑/平直/自动/按角度)、转换(网格/曲线/曲面/文本/融球/点云/体积/蜡笔)、设置原点、应用变换、清除变换、数据关联、形态键、顶点组、变换轴心/方向/吸附设置。
每条路径检查:Main 对象/网格发生变化、撤销/重做、保存重开一致;不支持的操作应给出结构化错误且不修改 Main。
## 4. 曲线编辑
- 进入曲线对象的编辑模式,选择控制点(Web 选择会写入原生 Curve 编辑数据)。
- “曲线”菜单:挤出/复制/删除/切换循环/手柄类型/样条类型/分离/添加顶点/细分/平滑/反向/重算法线/半径/倾斜/权重/着色/隐藏/显示/选择工具。
- 模态工具:挤出移动、复制移动、最短路径、绘制、钢笔、选择相连(拾取)。
- 检查:控制点选择与操作一致;撤销/重做、保存重开。
## 5. 已知未验证/限制
- 所有本轮实现均未运行负例、undo/redo、save/reopen、Worker restart 或 Chromium 自动化。
- 模态工具依赖原生画布与输入所有权;在 Web 视口点击会被原生画布接管。
- 修改器白名单新增类型的运行时求值未验证;Ocean/OpenVDB 依赖类型未编译。
- 选择读回依赖嵌入 Python 的 BMesh 查询;复杂模态操作后如高亮与实际选择不一致,请记录操作路径。
- route catalog 仍将大部分操作符标为 `SERVER_NATIVE`;本轮未做 `WEB_MAIN` 重新分类或 inventory 单元绑定。