# N-015 非 Mesh 几何数据块 状态:`in_progress`(本地有界切片已落地,VDB renderer/完整交互仍阻断) 更新时间:2026-08-12 ## 当前声明 当前声明覆盖 Blender 5.2 `.blend` 中有限非 Mesh 数据的稳定识别、Main 权威写回、undo/redo、 保存重开、真实 evaluated mesh 报告和 WNM 二进制分块。Curve cyclic/handle 已有有界 属性读写、多目标选择和单事务平移提交,未声明完整 topology editor、连续 gizmo preview、 VDB 体渲染或完整 Volume USD loss fixture。 | 数据族 | Reader | Web 预览 | 当前门 | | --- | --- | --- | --- | | legacy Curve | 控制点、spline offset、resolution | WNM 控制折线;depsgraph 真 mesh | `READY` | | legacy Surface | 控制点、spline offset、resolution | WNM 控制折线;depsgraph 真 mesh | `READY` | | Font | body、对齐、extrude/bevel/offset 与摘要 | depsgraph 真 mesh(源文本仍保留) | `READY`(无控制笼) | | Metaball | 元素类型、位置、半径、尺度 | bounded sphere proxy;depsgraph implicit mesh | `READY` | | PointCloud | position/radius/POINT 属性 | WNM 分块 Points | `READY`(空数据为 `summary-only`) | | Curves/Hair | position/radius/curve/POINT 属性 | WNM 分块 Points/curve line | `READY`(缺数据阻断) | | Volume | 项目内 OpenVDB path/grid metadata | 无 renderer;可取消 decoder API | `NON_MESH_RESOURCE_MISSING` 或预算阻断 | ## 已实现任务 1. `NonMeshDataIR` 加入 SceneIR schema 1,可选字段保持旧快照兼容。 2. parser 校验类型、状态、有限数、三元控制点、spline offset、Metaball 元素和错误码。 3. native reader 为数据块生成稳定 ID,并把对象 `dataId` 指向同一 ID;Web runtime 注册 `ID_MB`、`ID_PT` 和 `ID_VO`,不再把三类对象降为 Empty。 4. 单数据块最多读取 1M 点;越界或不完整数据返回 `NON_MESH_DATA_BUDGET_EXCEEDED`。 5. `NonMeshGeometryChunk` WNM schema 1 提供 65,536 点分块、SHA-256、属性 domain/storage、 256 MB 场景预算和 1M 点性能门;Worker/主线程/Offscreen 均传输并消费分块。 6. native reader 读取 PointCloud/Curves/Hair 的 position、radius、curve offset 和属性值, 不以摘要计数伪造点;Volume 提供项目路径、OpenVDB grid metadata 和可取消 decoder。 7. depsgraph 对 Curve/Surface/Font/Metaball 通过 `BKE_mesh_new_from_object` 输出真实位置、法线、 边/三角索引、UV、材质槽和 source face/edge mapping,并在 1M/2M 拓扑预算处结构化阻断。 Web ID registry 已注册 `ID_VF` 并在加载时恢复 Blender 未写入 `.blend` 的 `` 字体 引用;Curve/Surface/Font/Metaball 的几何计数、边界、面积和位置/索引矩均通过 Blender 5.2 desktop golden。 8. Main 已支持 Curve/Surface 控制点、resolution、有界 cyclic/handle 类型与 Bezier 左右 handle 坐标、Font body/geometry/layout 标量属性(spacing、line distance、word space、shear、font size、x/y offset)、逐字符 kern/material/style flags 和最多 256 个 textbox、 `.blend` 内已有/packed VFont 的 regular/bold/italic/bold-italic 四样式链接、 Metaball element 写回,以及 bounded Poly Curve create、delete、1D Poly/Bezier/NURBS conversion、 二维 Surface U/V dimensions/order/rational weight 网格替换和 Curve/Surface/Font/Metaball 数据块 重命名;一维多 spline 创建/删除/重排和批量 handle/cyclic 已由单个原子 Main 事务覆盖。 多 handle 选择、高亮和有界平移已由单个 Main transaction 覆盖,连续拖拽 preview 与 handle 专用 gizmo UI 仍阻断。单用户、undo/redo、save/reopen 由 `check-nonmesh-roundtrip.mjs` 验证。 9. 主线程与 OffscreenCanvas 对 PointCloud/Curve 控制点和 Bezier handle 代理提供 bounded raycast,并对 Mesh 的 VERT/EDGE/FACE 使用一致的三角顶点、边索引解析,回传既有 selection callback。selection history schema 2 覆盖跨对象、多 data block、多 element kind、revision/stale-hit、undo/redo 和有界 selected/unselected range patch,并兼容 schema 1。Bezier 左/右 handle 以全局控制点 映射独立拾取;多 handle 选择、高亮和有界平移经精确 Main 命令写回并通过 undo/redo、 save/reopen。完整连续 gizmo preview 仍未声明。 10. `queryNonMeshCapability(dataId)` 返回 N-015 `READY/BLOCKED` 与机器可读错误码;GLB 对未求值 非 Mesh 拒绝导出。Font/Metaball/二维 NURBS Surface 的 depsgraph 三角网格与 Curve 的 evaluated edge line primitive 已通过 GLB 导出和 Blender 5.2 桌面回导几何校验;零三角且零边的结果仍返回 `GLB_NON_MESH_UNMAPPED`,不生成空 primitive。确定性 USDA 1.0 序列化器将三角求值写为 `UsdGeomMesh`、edge-only 求值写为 `UsdGeomBasisCurves`,缺 buffer/空场景结构化阻断;四对象 已通过 USD-enabled Blender 5.2.0 LTS desktop reimport。PointCloud 使用 GLB `POINTS`/USD `UsdGeomPoints`,Curves/Hair 使用 GLB `LINES`/USD `UsdGeomBasisCurves`;radius 映射 USD widths,typed WNM 属性映射 primvars,GLB 属性损失结构化报告,7 对象 desktop reimport 已通过。 Volume loss fixture 仍由 VDB 资源/renderer 阻断。 11. Blender 5.2 fixture 已包含真实 PointCloud/Curves 属性;Chromium 主线程/Offscreen、真实 depsgraph、WNM 1M 性能测试均接入。 12. `CurveGizmoDragIR` 为 PREVIEW/COMMIT 请求绑定 data ID、base revision、轴向 delta 和最多 256 个去重 handle identity;现有 UI gizmo 在单次 pointer commit 时先执行 stale revision、 重复 handle、有限坐标和预算校验,再合并为一次 `setCurveTopology` Main 事务。连续 preview 仍未开放。 13. `test:vdb-availability` 确认当前 WASM build 为 `WITH_OPENVDB=OFF`、 `WITH_NANOVDB=ON` metadata-only,项目和本机资源库没有可用 `.vdb`。因此真实 decoder、 renderer 和 Volume loss fixture 继续 `BLOCKED`。 ## 后续分解 1. N-015-B3:接入真实 OpenVDB decoder 与体素纹理/射线步进;在此之前保持 Volume renderer 阻断。 2. N-015-C1:连续多 handle 拖拽 preview 与专用 gizmo UI;多 handle 选择、高亮、单事务平移、 多 spline 创建/删除/重排、批量 handle/cyclic editor transaction 和二维 Surface U/V topology/order/rational weight 网格替换已完成。 3. N-015-C2:任意外部路径的新字体导入与资源沙箱;已有/packed VFont 的四 style link Main 写回、字符级样式、kern/material 与 textbox 已完成并通过 PFB desktop/WASM golden。 4. N-015-D1:跨对象 selection history、多目标 element identity、range patch、左右 handle raycast 和多 handle Main 写回已完成;连续拖拽 preview 归入 C1 阻断。 5. N-015-D2:evaluated preview 与源控制笼分层显示、WebGPU 等价。 6. N-015-E1:补齐 Volume 的完整 loss fixture;PointCloud/Curves/Hair、Curve line bake、真实 4x4 NURBS Surface mesh、desktop geometry golden、7 对象 GLB 与 USDA desktop round-trip 已通过。 7. N-015-E2:100k/1M WASM/GPU 内存、Worker restart 和 Chromium OPFS quota;Chromium 64 KiB 真实 quota、失败后旧 revision 保持、Worker restart 恢复已通过。后续浏览器验收 仅以 Chromium 为基线,不配置 Firefox/WebKit。 ## 停止条件 - `summary-only` 不得进入 `READY`。 - legacy 控制折线不得标记为 evaluated/tessellated curve。 - Metaball sphere proxy 不得用于导出或保存为求值曲面。 - Volume decoder/renderer、Hair 属性 buffer 缺失时不得生成占位几何。 - Metaball sphere proxy 不得进入 GLB;GLB 只能消费 depsgraph evaluated mesh。 - 任意新增 Main authoring 命令在 save/reopen 与 undo/redo 完成前不得开放 UI。 ## 验收命令 ```bash source tools/web/emscripten-env.sh cmake --build build_web_blender6 --target web_engine -- -j8 bash tools/web/install-web-engine-assets.sh build_blender_5.2.0/bin/blender -b --factory-startup \ --python tools/web/generate-nonmesh-fixture.py -- tests/files/web/nonmesh_scene.blend npm --prefix web run typecheck npm --prefix web run lint npm --prefix web run test:nonmesh-roundtrip npm --prefix web run test:nonmesh-desktop-golden npm --prefix web run test:nonmesh-glb-blender-roundtrip npm --prefix web run test:nonmesh-usd-serialization BLENDER_BIN=/path/to/usd-enabled/blender \ npm --prefix web run test:nonmesh-usd-blender-roundtrip npm --prefix web run test:nonmesh-binary npm --prefix web run test:nonmesh-interaction npm --prefix web run test:vdb-availability npm --prefix web run test:vdb WEB_TEST_PORT=5349 npm --prefix web run test:e2e -- -g "real OPFS quota|reports quota exhaustion" WEB_TEST_PORT=5201 npm --prefix web run test:e2e -- -g "N-015|non-mesh" ```