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

3.0 KiB

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

  • blender/osmassets/fountain.py contains the fountain assembly behavior and imports only bpy-layer-safe dependencies.
  • blender/generate_scene.py imports and calls the new fountain module; no inline add_fountain() function remains there.
  • Scene counts and SCENE_DONE JSON keys remain unchanged.
  • python3 -m unittest blender/tests/test_pure.py passes.
  • python3 -m py_compile blender/osmassets/fountain.py passes.
  • python3 -m py_compile blender/generate_scene.py passes.
  • 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.