Files
osmWorkflow/.trellis/tasks/archive/2026-08/08-03-extract-fountain-module/prd.md

74 lines
3.0 KiB
Markdown

# Extract fountain module
## Goal
Move the fountain assembly code out of `blender/generate_scene.py` into a
dedicated bpy-layer module, keeping the generated `.blend` / `.glb` structure
unchanged. This is the first low-risk step toward the documented P2 feature
module / registry direction.
## Background
- `.trellis/spec/guides/artifact-parity-guide.md` records P2 as partial:
`water.py`, `grass.py`, `scrub.py`, and `tree.py` exist, but `building`,
`fountain`, and `roads` still live in `generate_scene.py`.
- `blender/generate_scene.py:639` defines `add_fountain()` inline.
- `blender/generate_scene.py:895` dispatches OSM point features with
`amenity=fountain`, calls `add_fountain("Fountain_" + id, ...)`, and
increments `counts["fountain_count"]`.
- `blender/osmassets/catalog.py` already owns the three fountain materials:
`fountain_stone`, `fountain_water`, and `fountain_spray`.
- This task is a pure refactor. It must not change fountain geometry, object
names, materials, custom properties, counts, stdout markers, or Cesium export
behavior.
## Requirements
1. Add a new bpy-layer module at `blender/osmassets/fountain.py`.
2. Move the current fountain assembly behavior from `generate_scene.py` into
the new module.
3. Keep `generate_scene.py` responsible for:
- creating fountain materials from `catalog.MATERIALS`;
- filtering `point_features` for `amenity=fountain`;
- projecting coordinates;
- incrementing `counts["fountain_count"]`.
4. Preserve the existing object names:
- `Fountain_<id>_Basin`
- `Fountain_<id>_Water`
- `Fountain_<id>_Pedestal`
- `Fountain_<id>_Water_Crown`
- `Fountain_<id>_Droplet_<n>`
5. Preserve the existing basin custom property:
`osm_feature = "amenity=fountain"`.
6. Do not introduce a full `features/` registry in this task.
7. Do not modify `building`, `roads`, material definitions, `MATERIALS` order,
`ROAD_LAYERS` order, stdout markers, or parity ignore lists.
8. Do not fix unrelated documented defects D1, D2, or D3.
## Acceptance Criteria
- [x] `blender/osmassets/fountain.py` contains the fountain assembly behavior
and imports only bpy-layer-safe dependencies.
- [x] `blender/generate_scene.py` imports and calls the new fountain module;
no inline `add_fountain()` function remains there.
- [x] Scene counts and `SCENE_DONE` JSON keys remain unchanged.
- [x] `python3 -m unittest blender/tests/test_pure.py` passes.
- [x] `python3 -m py_compile blender/osmassets/fountain.py` passes.
- [x] `python3 -m py_compile blender/generate_scene.py` passes.
- [x] A before/after parity comparison is run for the Blender/Cesium stages and
any non-ignored diff is either absent or explicitly explained as
expected. For this refactor, the expected result is no contract diff.
## Out Of Scope
- Full feature registry design or implementation.
- Building extraction.
- Road extraction.
- Fountain visual redesign or geometry changes.
- Material contract changes.
- Documentation-only cleanup of stale comments such as D3.
## Open Questions
None.