Files
osmWorkflow/.trellis/tasks/archive/2026-08/08-03-material-export-contract/implement.md

4.1 KiB
Raw Blame History

执行计划Material export contract

对应 prd.md / design.md。按序执行,避免把视觉调参和契约迁移混在一起。


前置检查

python3 ./.trellis/scripts/get_context.py --mode packages
python3 -m unittest discover blender/tests
git status --porcelain

可选但推荐:若本机 Blender / 输出产物可用,先采集 before parity

node scripts/parity.js capture material-contract-before

Step 1 — 迁移 catalog 契约

  • blender/osmassets/catalog.py 中把有效 Cesium 覆盖迁入对应 MATERIALS[*]["cesium"]
  • 不把 "Office White Metal Facade" 迁入新契约源
  • 删除或消解 catalog.CESIUM_EXPORT 死代码状态
  • 保持 MATERIALS 顺序不变,不在中间插入新材质

检查:

grep -n "CESIUM_EXPORT\\|Office White Metal Facade\\|cesium" blender/osmassets/catalog.py

Step 2 — 材质创建时写自定义属性

  • blender/osmassets/materials.py 增加 cesium_export 写入 helper
  • from_spec() 对每个 material 应用 helper
  • cesium 的材质清理旧属性,避免复用同名材质时残留

检查点:

python3 -m unittest discover blender/tests

Step 3 — 导出器优先读 contract

  • blender/export_cesium.py 增加 cesium_contract(material) helper
  • make_export_material() 使用 contract 优先、旧表回退
  • cesium_tinted_image() 改为由调用方传入 tint
  • 旧四张表保留为旧 .blend 兼容层,并注释说明
  • alpha-clipped foliage 分支不做行为重构

检查:

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 更新

  • 更新 .trellis/spec/blender/module-structure.md
  • 更新 .trellis/spec/blender/asset-generation.md
  • 必要时更新 .trellis/spec/guides/artifact-parity-guide.md 的 P3 状态

移除或改写“catalog.CESIUM_EXPORT 是死代码 / 改它不会生效 / P3 未做”的当前事实。

Step 6 — 全量验收

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-beforematerial-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 确认 GrassOffice White Plaster FacadeIndustrial White Ribbed FacadeFactory Blue Metal Roofcesium_export hanyang-block 还确认 Tree Crown Dark / Tree Crown Light。默认样本不创建 Tree Crown,另用 Blender --python-expr 构造 catalog.MATERIALS["tree_crown"] 确认该材质也写入 cesium_export