# 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 `/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 - [x] AC3.1 编译器输出 `manifest.json`,两个有效区域(`fengshu-er-road`、`nantaizi-lake-innovation-valley`)均含全部 12 图层声明 - [x] AC3.2 `catalog.NATIVE_ROAD_LAYERS` 已删除,Blender 无硬编码道路图层表 - [x] AC3.3 `.blend` 结构摘要对 Phase 0 基线一致 (走 `.trellis/spec/guides/artifact-parity-guide.md`) - [x] AC3.4 **实测**:向编译器加一个 throwaway 图层 + manifest 声明, 不改宿主任何代码,跑 blender 阶段确认它被渲染出来;验证后回滚该图层 (父任务 AC5,见 design §3.4) - [x] AC3.5 `role: "semantic"` 的图层被 Blender 正确跳过(不产生几何) - [x] AC3.6 `center_lines` 的 white/非 white 与 `lane_separators` 的 yellow/非 yellow 分流行为与改造前一致 - [x] 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` 的改动 - 建筑/植被/水体渲染逻辑