Files
osmWorkflow/.trellis/tasks/08-03-design-feature-registry/prd.md
2026-08-03 14:02:28 +08:00

95 lines
4.3 KiB
Markdown

# Design feature registry
## Goal
Introduce a conservative Blender feature registry so `generate_scene.py` no
longer hard-codes every OSM feature dispatch branch, while keeping generated
`.blend` / `.glb` / scene metadata and stdout contracts unchanged.
The user value is maintainability: adding or moving a Blender feature should
become a registration-level edit plus a feature module implementation, not a
new branch woven through the main scene builder.
## Background
- P2 module extraction is now complete for current feature assembly modules:
`water.py`, `grass.py`, `scrub.py`, `tree.py`, `fountain.py`,
`building.py`, and `roads.py` exist under `blender/osmassets/`.
- `.trellis/spec/guides/artifact-parity-guide.md` records the remaining P2
gap as the missing `features/` registry.
- `blender/generate_scene.py` still owns the orchestration sequence:
material creation, OSM way dispatch, road GeoJSON/fallback dispatch, tree
collection/fallback, fountain point dispatch, camera focus points, scene
metadata, save/render, and `SCENE_DONE`.
- Artifact parity is mandatory because this is intended as a pure refactor.
## Requirements
1. Add a new Blender-side registry module under `blender/osmassets/`, expected
path `blender/osmassets/features.py`.
2. Replace the inline OSM way `if` / `elif` feature dispatch in
`generate_scene.py` with registry-driven dispatch while preserving exact
behavior and order:
- water before grass;
- grass before scrub;
- scrub before tree-row collection;
- tree-row collection before building;
- first matching handler wins, as the current `elif` chain does.
3. Make the current feature phases explicit in code:
- OSM way feature phase;
- road GeoJSON / OSM fallback phase;
- tree placement phase;
- point prop phase for fountains.
4. Keep `generate_scene.py` responsible for high-level scene contracts:
- CLI parsing and tree-style validation;
- collection creation and collection order;
- material creation order;
- `counts`, `road_counts`, tree counts, and `focus_points` ownership;
- `catalog.check_layers()` and exact `Layer catalog warning:` print text;
- scene custom properties;
- `SCENE_DONE` marker and JSON shape.
5. Do not change current feature module assembly signatures unless the change
is a mechanical adapter around the same behavior.
6. Do not reorder `catalog.MATERIALS`, `catalog.ROAD_LAYERS`, collection
creation, object creation phases, or `SCENE_DONE` fields.
7. Do not introduce a second list of osm2streets road layer ids. Road layer
iteration must still derive from `catalog.ROAD_LAYERS`.
8. Do not fix unrelated known defects D1-D3 in this task.
## Acceptance Criteria
- [ ] `blender/osmassets/features.py` exists and contains the registry /
dispatcher contract for Blender feature phases.
- [ ] `generate_scene.py` uses the registry for OSM way feature dispatch; the
previous inline `if` / `elif` way feature chain is removed or reduced to
small handler callbacks.
- [ ] Current generated object names, mesh names, material creation order,
collection order, scene properties, and `SCENE_DONE` JSON remain
unchanged.
- [ ] `road_counts`, `counts`, tree counts, and `focus_points` continue to be
owned by `generate_scene.py` or by explicit objects passed from it, not
hidden in global module state.
- [ ] `catalog.check_layers()` warning behavior remains in `generate_scene.py`
with the exact `Layer catalog warning:` text.
- [ ] `python3 -m py_compile blender/osmassets/features.py` passes.
- [ ] `python3 -m py_compile blender/generate_scene.py` passes.
- [ ] `python3 -m unittest blender/tests/test_pure.py` passes.
- [ ] Blender/Cesium parity before/after is run for
`nantaizi-lake-innovation-valley` and `hanyang-block`; expected compare
result is `identical` for both.
## Out Of Scope
- Changing feature behavior, geometry, z values, material definitions, material
order, or catalog declarations.
- Moving material creation into feature modules.
- Moving scene metadata / `SCENE_DONE` construction out of `generate_scene.py`.
- Reworking tree model loading, procedural tree fallback, grass tuft loading,
scrub bush loading, or camera focus logic beyond adapter-level plumbing.
- Adding new rendered feature types.
- Changing parity ignore lists or stdout marker parsing.
## Open Questions
None.