91 lines
4.2 KiB
Markdown
91 lines
4.2 KiB
Markdown
# Phase 3:道路与建筑渲染分离
|
||
|
||
父任务:`.trellis/tasks/08-25-road-compiler-extraction/`
|
||
技术设计:父任务 `design.md` §3(含 manifest 形状与 Blender 侧改造方案)
|
||
|
||
## Goal
|
||
|
||
让编译器自声明图层,Blender 改为读 manifest 而非硬编码表;
|
||
道路渲染从 `generate_scene.py` 抽离为独立模块,建筑/植被/水体保持原位。
|
||
|
||
**这是全案价值最高的一步** —— 它把一张跨仓库重复的表变成生成物,
|
||
使"编译器加图层忘了改宿主"这类静默错误在结构上不可能。
|
||
|
||
## 背景:当前的静默错误风险
|
||
|
||
`blender/osmassets/catalog.py:53` 的 `NATIVE_ROAD_LAYERS` 有 10 项,
|
||
而编译器写 12 个 geojson —— `lane_centerlines` 与 `connectors` 是语义层不参与渲染。
|
||
|
||
**但这个事实只存在于这张表的省略里,编译器侧没有任何声明。**
|
||
拆仓库之后,这张表和它描述的对象分处两个仓库,漂移只是时间问题。
|
||
|
||
`.trellis/spec/pipeline/index.md` 首页已经把图层表标为「最容易出静默错误」。
|
||
|
||
## Requirements
|
||
|
||
### R3.1 编译器输出 layer manifest
|
||
|
||
`<outDir>/manifest.json`,形状见父任务 `design.md` §3.2。要点:
|
||
|
||
- 每个图层声明 `source`(geojson 文件名)、`role`、以及渲染角色所需的 `materialLayer`
|
||
- `role: "semantic"` 显式标记不渲染的图层 —— 把省略变成声明
|
||
- `splitBy` 表达按属性分流到不同材质的逻辑
|
||
(当前 `generate_scene.py:815-819` 硬编码的 `color != "white"` / `color == "yellow"`)
|
||
- 材质本体(颜色、z 高度、贴图)**仍归宿主** `catalog.py::MATERIALS`;
|
||
编译器不懂渲染,只声明"我有哪些图层、什么角色、该用哪个材质槽"
|
||
|
||
### R3.2 Blender 侧改造
|
||
|
||
- `generate_scene.py` 内道路分支抽为 `blender/osmassets/native_roads.py`
|
||
- 新模块读 manifest 遍历,不再查硬编码表
|
||
- 删除 `catalog.NATIVE_ROAD_LAYERS`
|
||
- 建筑(`handle_building` / `dispatch_ways`)、植被、水体**保持原位不动**
|
||
|
||
### R3.3 契约版本处理
|
||
|
||
新增 `manifest.json` 是**向后兼容的增量**(旧消费方忽略未知文件即可),
|
||
但 Blender 改为依赖它之后就成了必需项。
|
||
|
||
- 契约文档记录:`manifest.json` 自 v1.1 起为必需输出
|
||
- 宿主声明所需最低契约版本
|
||
|
||
### R3.4 跨层一致性检查
|
||
|
||
按 `.trellis/spec/guides/cross-layer-thinking-guide.md`:
|
||
本改动同时触碰 JS(编译器输出)、Python(Blender 消费)、契约文档三层,
|
||
必须走该指南的检查清单。
|
||
|
||
## Acceptance Criteria
|
||
|
||
- [ ] AC3.1 编译器输出 `manifest.json`,三区域均含全部 12 图层声明
|
||
- [ ] AC3.2 `catalog.NATIVE_ROAD_LAYERS` 已删除,Blender 无硬编码道路图层表
|
||
- [ ] AC3.3 `.blend` 结构摘要对 Phase 0 基线一致
|
||
(走 `.trellis/spec/guides/artifact-parity-guide.md`)
|
||
- [ ] AC3.4 **实测**:向编译器加一个 throwaway 图层 + manifest 声明,
|
||
不改宿主任何代码,跑 blender 阶段确认它被渲染出来;验证后回滚该图层
|
||
(父任务 AC5,见 design §3.4)
|
||
- [ ] AC3.5 `role: "semantic"` 的图层被 Blender 正确跳过(不产生几何)
|
||
- [ ] AC3.6 `center_lines` 的 white/非 white 与 `lane_separators` 的 yellow/非 yellow
|
||
分流行为与改造前一致
|
||
- [ ] AC3.7 建筑/植被/水体渲染代码未被修改(`git diff` 验证范围)
|
||
|
||
## 依赖与顺序
|
||
|
||
- **前置**:Phase 2 完成(编译器已独立,manifest 才有"跨仓库契约"的意义)
|
||
- 与 Phase 4 无依赖,可并行
|
||
- 完成本阶段后,父任务 Goal 中的「道路与建筑渲染分离」才算达成
|
||
|
||
## 风险
|
||
|
||
| 风险 | 缓解 |
|
||
|---|---|
|
||
| `splitBy` 表达力不足,覆盖不了现有分流逻辑 | 先枚举 `generate_scene.py` 里全部分流分支,再定 manifest schema |
|
||
| 材质槽名在两侧漂移 | manifest 里的 `materialLayer` 必须能被宿主校验:Blender 侧加断言,未知材质槽直接报错而非静默跳过 |
|
||
| `.blend` 结构摘要对比粒度不够,漏掉几何差异 | 除结构摘要外,加渲染预览图人工对照 |
|
||
|
||
## Out of Scope
|
||
|
||
- 材质定义搬去编译器(材质属渲染,归宿主)
|
||
- osm2streets legacy 图层表 `ROAD_LAYERS` 的改动
|
||
- 建筑/植被/水体渲染逻辑
|