chore(task): archive 08-03-extract-fountain-module
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
|
||||
@@ -0,0 +1,53 @@
|
||||
# Design
|
||||
|
||||
## Architecture
|
||||
|
||||
`fountain.py` will join the existing bpy-layer feature modules under
|
||||
`blender/osmassets/`. It may import `bpy`, `math`, and the collection helper
|
||||
needed to preserve current object linking behavior.
|
||||
|
||||
The module will expose one function:
|
||||
|
||||
```python
|
||||
def assemble(name, x, y, collection, materials):
|
||||
...
|
||||
```
|
||||
|
||||
The signature mirrors the existing inline `add_fountain(name, x, y, collection,
|
||||
materials)` call site to keep the migration mechanical and parity-friendly.
|
||||
|
||||
## Boundaries
|
||||
|
||||
- `generate_scene.py` keeps OSM feature filtering, projection, material creation,
|
||||
and count ownership.
|
||||
- `fountain.py` owns only Blender object creation for one fountain at already
|
||||
projected `(x, y)` coordinates.
|
||||
- No pure-Python module may import `bpy`; this module is explicitly in the
|
||||
bpy layer, like `water.py`, `grass.py`, `scrub.py`, and `tree.py`.
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. `generate_scene.py` creates `fountain_mats` from `catalog.MATERIALS`.
|
||||
2. `generate_scene.py` finds point features where `tags.amenity == "fountain"`.
|
||||
3. `Projector.xy()` converts the OSM coordinate to local meters.
|
||||
4. `fountain.assemble("Fountain_" + id, fx, fy, props_c, fountain_mats)` creates
|
||||
the existing basin, water disk, pedestal, crown, and droplets.
|
||||
5. `generate_scene.py` increments `counts["fountain_count"]`.
|
||||
|
||||
## Compatibility
|
||||
|
||||
The refactor must preserve all generated object names, primitive dimensions,
|
||||
materials, smoothing flags, and custom properties. Cesium export reads the
|
||||
resulting `.blend`; it should see an equivalent scene graph.
|
||||
|
||||
## Trade-Offs
|
||||
|
||||
A full feature registry is intentionally deferred. Starting with a one-module
|
||||
extraction keeps the diff small and lets parity isolate any regression to the
|
||||
fountain move before higher-risk building or road work.
|
||||
|
||||
## Rollback
|
||||
|
||||
Rollback is straightforward: remove `fountain.py`, restore the inline
|
||||
`add_fountain()` function, remove the module import, and restore the original
|
||||
call site.
|
||||
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
|
||||
@@ -0,0 +1,40 @@
|
||||
# Implementation Plan
|
||||
|
||||
## Checklist
|
||||
|
||||
1. Capture a parity baseline before product-code edits.
|
||||
2. Add `blender/osmassets/fountain.py` with the current fountain assembly logic.
|
||||
3. Import the module in `blender/generate_scene.py`.
|
||||
4. Remove inline `add_fountain()` from `generate_scene.py`.
|
||||
5. Replace the call site with `fountain.assemble(...)`.
|
||||
6. Run Python validation:
|
||||
- `python3 -m py_compile blender/osmassets/fountain.py`
|
||||
- `python3 -m py_compile blender/generate_scene.py`
|
||||
- `python3 -m unittest blender/tests/test_pure.py`
|
||||
7. Capture parity after the refactor.
|
||||
8. Compare before/after parity snapshots and inspect any non-ignored diff.
|
||||
9. Update `.trellis/spec` or `docs/changelog.md` only if the work reveals a
|
||||
durable new constraint or user-visible change.
|
||||
10. Commit, archive the task, and record the journal entry.
|
||||
|
||||
## Validation Commands
|
||||
|
||||
```bash
|
||||
node scripts/parity.js capture fountain-module-before --stages blender,cesium
|
||||
python3 -m py_compile blender/osmassets/fountain.py
|
||||
python3 -m py_compile blender/generate_scene.py
|
||||
python3 -m unittest blender/tests/test_pure.py
|
||||
node scripts/parity.js capture fountain-module-after --stages blender,cesium
|
||||
node scripts/parity.js compare fountain-module-before fountain-module-after
|
||||
```
|
||||
|
||||
## Risk Points
|
||||
|
||||
- `link_object_to_collection()` must be used the same way as before so object
|
||||
collection membership stays unchanged.
|
||||
- The basin custom property must remain on the basin object only.
|
||||
- Droplet order and names must stay stable.
|
||||
- `math` usage may move with the function; remove the import from
|
||||
`generate_scene.py` only if no remaining code uses it.
|
||||
- Parity is mandatory because this is a pure refactor of bpy-layer scene
|
||||
generation.
|
||||
@@ -0,0 +1,73 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "extract-fountain-module",
|
||||
"name": "extract-fountain-module",
|
||||
"title": "Extract fountain module",
|
||||
"description": "",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": null,
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "dingkang",
|
||||
"assignee": "dingkang",
|
||||
"createdAt": "2026-08-03",
|
||||
"completedAt": "2026-08-03",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
Reference in New Issue
Block a user