115 lines
4.1 KiB
Markdown
115 lines
4.1 KiB
Markdown
# 执行计划:Material export contract
|
||
|
||
> 对应 `prd.md` / `design.md`。按序执行,避免把视觉调参和契约迁移混在一起。
|
||
|
||
---
|
||
|
||
## 前置检查
|
||
|
||
```bash
|
||
python3 ./.trellis/scripts/get_context.py --mode packages
|
||
python3 -m unittest discover blender/tests
|
||
git status --porcelain
|
||
```
|
||
|
||
可选但推荐:若本机 Blender / 输出产物可用,先采集 before parity:
|
||
|
||
```bash
|
||
node scripts/parity.js capture material-contract-before
|
||
```
|
||
|
||
## Step 1 — 迁移 catalog 契约
|
||
|
||
- [x] 在 `blender/osmassets/catalog.py` 中把有效 Cesium 覆盖迁入对应
|
||
`MATERIALS[*]["cesium"]`
|
||
- [x] 不把 `"Office White Metal Facade"` 迁入新契约源
|
||
- [x] 删除或消解 `catalog.CESIUM_EXPORT` 死代码状态
|
||
- [x] 保持 `MATERIALS` 顺序不变,不在中间插入新材质
|
||
|
||
检查:
|
||
|
||
```bash
|
||
grep -n "CESIUM_EXPORT\\|Office White Metal Facade\\|cesium" blender/osmassets/catalog.py
|
||
```
|
||
|
||
## Step 2 — 材质创建时写自定义属性
|
||
|
||
- [x] 在 `blender/osmassets/materials.py` 增加 `cesium_export` 写入 helper
|
||
- [x] `from_spec()` 对每个 material 应用 helper
|
||
- [x] 无 `cesium` 的材质清理旧属性,避免复用同名材质时残留
|
||
|
||
检查点:
|
||
|
||
```bash
|
||
python3 -m unittest discover blender/tests
|
||
```
|
||
|
||
## Step 3 — 导出器优先读 contract
|
||
|
||
- [x] 在 `blender/export_cesium.py` 增加 `cesium_contract(material)` helper
|
||
- [x] `make_export_material()` 使用 contract 优先、旧表回退
|
||
- [x] `cesium_tinted_image()` 改为由调用方传入 tint
|
||
- [x] 旧四张表保留为旧 `.blend` 兼容层,并注释说明
|
||
- [x] alpha-clipped foliage 分支不做行为重构
|
||
|
||
检查:
|
||
|
||
```bash
|
||
grep -n "EXPORT_TINTS\\|EXPORT_METALLIC_OVERRIDES\\|EXPORT_BASE_COLOR_OVERRIDES\\|EXPORT_EMISSION_OVERRIDES\\|cesium_contract" blender/export_cesium.py
|
||
```
|
||
|
||
## Step 4 — 验证新 `.blend` 带 contract
|
||
|
||
用一个区域跑 `blender` 阶段或 parity capture 后,使用 Blender/Python 摘要确认材质自定义属性存在。
|
||
可接受的验证方式:
|
||
|
||
- 从 `blender/tools/scene_digest.py` 输出里看材质 custom property
|
||
- 或用 Blender `--background --python-expr` 检查若干材质的 `cesium_export`
|
||
|
||
目标材质至少覆盖:
|
||
|
||
- `Grass`
|
||
- `Office White Plaster Facade`
|
||
- `Industrial White Ribbed Facade`
|
||
- `Factory Blue Metal Roof`
|
||
- `Tree Crown`
|
||
|
||
## Step 5 — Spec 更新
|
||
|
||
- [x] 更新 `.trellis/spec/blender/module-structure.md`
|
||
- [x] 更新 `.trellis/spec/blender/asset-generation.md`
|
||
- [x] 必要时更新 `.trellis/spec/guides/artifact-parity-guide.md` 的 P3 状态
|
||
|
||
移除或改写“`catalog.CESIUM_EXPORT` 是死代码 / 改它不会生效 / P3 未做”的当前事实。
|
||
|
||
## Step 6 — 全量验收
|
||
|
||
```bash
|
||
python3 -m unittest discover blender/tests
|
||
node scripts/parity.js capture material-contract-after
|
||
node scripts/parity.js compare material-contract-before material-contract-after
|
||
git status --porcelain
|
||
```
|
||
|
||
若没有可用 before capture,则先在未改动代码上 capture before;如果实现已经完成但 before 缺失,
|
||
不要伪造 parity 结论,明确记录“未运行 before/after parity”的缺口。
|
||
|
||
## 回滚点
|
||
|
||
- Step 1 后如果纯测试失败,回滚 `catalog.py` 迁移。
|
||
- Step 3 后如果旧 `.blend` 导出行为不清晰,保留旧表优先,重新收窄 contract 读取范围。
|
||
- Parity 若出现非自定义属性以外的 `.blend` / GLB 结构差异,先修实现,不扩大忽略名单。
|
||
|
||
## 实施记录
|
||
|
||
- 2026-08-03:实现完成。`node scripts/parity.js capture material-contract-before`
|
||
与 `material-contract-after` 均成功。
|
||
- `node scripts/parity.js compare material-contract-before material-contract-after`
|
||
返回差异 15 项:仅 `.blend` 材质 `props.cesium_export` 新增和 `.blend` bytes 变化;
|
||
未出现对象、网格、材质 PBR、GLB 结构或 metadata 差异。
|
||
- after snapshot 确认 `Grass`、`Office White Plaster Facade`、
|
||
`Industrial White Ribbed Facade`、`Factory Blue Metal Roof` 带 `cesium_export`;
|
||
`hanyang-block` 还确认 `Tree Crown Dark` / `Tree Crown Light`。默认样本不创建
|
||
`Tree Crown`,另用 Blender `--python-expr` 构造 `catalog.MATERIALS["tree_crown"]`
|
||
确认该材质也写入 `cesium_export`。
|