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

4.3 KiB

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.