Files
HartOMat/plan.md
T
Hartmut 393e4b92a7 refactor(P1): complete pipeline cleanup — M1 dead code + M3 blender split
M1 dead code removal:
- admin.py: remove VALID_STL_QUALITIES + stl_quality (7 locations)
- frontend: remove stl_quality from 6 files (api/orders.ts, api/worker.ts,
  WorkerActivity.tsx, RenderInfoModal.tsx, helpTexts.ts, mocks/handlers.ts)
- blender_render.py: delete _mark_sharp_and_seams() — dead, never called (62 lines)
- step_processor.py: delete _render_via_service() + 2 elif renderer=="threejs" branches
- renderproblems_tmp/: remove 3 orphaned debug images

M3 blender_render.py decomposition (858 → 248 lines):
- _blender_gpu.py: activate_gpu(), configure_engine()
- _blender_import.py: import_glb(), apply_rotation()
- _blender_materials.py: FAILED_MATERIAL_NAME, assign_failed_material(),
  build_mat_map_lower(), apply_material_library()
- _blender_camera.py: setup_auto_camera(), setup_auto_lights()
- _blender_scene.py: ensure_collection(), apply_smooth_batch(),
  apply_sharp_edges_from_occ(), setup_shadow_catcher()
- Entry-point: sys.path.insert for submodule discovery; arg-parse + Mode A/B orchestration only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 22:19:59 +01:00

184 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Plan: Priority 1 — Pipeline Cleanup (M1 Dead Code + M3 blender_render Split)
## Context
ROADMAP Priority 1 is "In Progress". M2 (`step_tasks.py` decomposed to `domains/pipeline/tasks/`) is **done**. Two milestones remain:
- **M1**: Delete dead-code directories, remove `stl_quality` from admin/frontend surface, remove dead functions
- **M3**: Decompose `blender_render.py` (920 lines) into focused submodules
---
## Affected Files
| File | Change |
|------|--------|
| `blender-renderer/` | DELETE directory |
| `threejs-renderer/` | DELETE directory |
| `renderproblems_tmp/` | DELETE directory |
| `backend/app/api/routers/admin.py` | Remove `stl_quality` + `VALID_STL_QUALITIES` (7 locations) |
| `frontend/src/api/orders.ts` | Remove `stl_quality?: string` |
| `frontend/src/api/worker.ts` | Remove `stl_quality?: string` |
| `frontend/src/pages/WorkerActivity.tsx` | Remove STL quality KV row |
| `frontend/src/components/renders/RenderInfoModal.tsx` | Remove STL quality display row |
| `frontend/src/help/helpTexts.ts` | Remove `setting.stl_quality` entry |
| `backend/app/services/step_processor.py` | Remove `_render_via_service()` + dead `elif renderer == "threejs"` |
| `render-worker/scripts/blender_render.py` | Remove `_mark_sharp_and_seams()`; thin to entry-point after submodule extraction |
| `render-worker/scripts/_blender_gpu.py` | CREATE — `activate_gpu()` |
| `render-worker/scripts/_blender_import.py` | CREATE — `import_glb()`, `apply_rotation()` |
| `render-worker/scripts/_blender_materials.py` | CREATE — `build_mat_map_lower()`, `apply_material_library()`, `assign_failed_material()` |
| `render-worker/scripts/_blender_camera.py` | CREATE — `setup_auto_camera()`, `setup_auto_lights()` |
| `render-worker/scripts/_blender_scene.py` | CREATE — `ensure_collection()`, `apply_smooth_batch()`, `apply_sharp_edges_from_occ()`, `setup_shadow_catcher()` |
---
## Tasks (in order)
### [x] Task M1-1: Delete obsolete directories
- **What**: `rm -rf blender-renderer/ threejs-renderer/ renderproblems_tmp/`
- **Acceptance gate**: `ls blender-renderer/ threejs-renderer/ renderproblems_tmp/` → all "No such file"
- **Dependencies**: none
- **Risk**: Zero — no active source files
---
### [x] Task M1-2: Remove stl_quality from admin.py
- **File**: `backend/app/api/routers/admin.py`
- **What**: Delete all 7 references:
1. `VALID_STL_QUALITIES = {"low", "high"}` constant
2. `"stl_quality": "low"` from `SETTINGS_DEFAULTS`
3. `stl_quality: str = "low"` from `SettingsOut`
4. `stl_quality: str | None = None` from `SettingsUpdate`
5. `stl_quality=raw["stl_quality"],` from `_settings_to_out()`
6. `if body.stl_quality is not None and body.stl_quality not in VALID_STL_QUALITIES:` validation block
7. `if body.stl_quality is not None: updates["stl_quality"] = body.stl_quality` update block
- **Acceptance gate**: `grep -n "stl_quality\|VALID_STL_QUALITIES" backend/app/api/routers/admin.py` → 0 matches
- **Dependencies**: none
- **Risk**: Low — the DB key remains (harmless); pipeline internally still uses `gltf_*_linear_deflection`
---
### [x] Task M1-3: Remove stl_quality from frontend
- **Files**:
- `frontend/src/api/orders.ts` — remove `stl_quality?: string`
- `frontend/src/api/worker.ts` — remove `stl_quality?: string`
- `frontend/src/pages/WorkerActivity.tsx` — remove STL quality KV row
- `frontend/src/components/renders/RenderInfoModal.tsx` — remove STL quality row
- `frontend/src/help/helpTexts.ts` — remove `setting.stl_quality` entry
- **Acceptance gate**: `grep -rn "stl_quality" frontend/src/` → 0 matches; `npx tsc --noEmit` passes
- **Dependencies**: M1-2
- **Risk**: Low — all uses are optional fields (`?:`)
---
### [x] Task M1-4: Remove dead _mark_sharp_and_seams from blender_render.py
- **File**: `render-worker/scripts/blender_render.py`
- **What**: Delete the `_mark_sharp_and_seams()` function (lines 196256 approx). It is defined but never called — `_apply_sharp_edges_from_occ()` is the active implementation.
- **Acceptance gate**: `grep -n "_mark_sharp_and_seams" render-worker/scripts/blender_render.py` → 0 matches
- **Dependencies**: none
- **Risk**: Zero — verifiably never called
---
### [x] Task M1-5: Remove dead code from step_processor.py
- **File**: `backend/app/services/step_processor.py`
- **What**: Delete `_render_via_service()` function and the `elif renderer == "threejs":` branch (which only logs a warning and falls through)
- **Acceptance gate**: `grep -n "_render_via_service\|renderer == .threejs" backend/app/services/step_processor.py` → 0 matches
- **Dependencies**: M1-1
- **Risk**: Low — function is only referenced from within the dead branch
---
### [x] Task M3-1: Create _blender_gpu.py
- **File**: `render-worker/scripts/_blender_gpu.py` (NEW)
- **What**: Extract `_activate_gpu()` from `blender_render.py` into a standalone module. Refactor to accept `cycles_device: str` parameter instead of reading a module-level global. Rename to `activate_gpu()`.
- **Key signature**: `def activate_gpu(cycles_device: str = "auto") -> str | None`
- **Acceptance gate**: `grep -c "def _activate_gpu" render-worker/scripts/blender_render.py` → 0; function callable as `from _blender_gpu import activate_gpu`
- **Dependencies**: M1-4
- **Risk**: Medium — must pass `sys.path` correctly so Blender Python finds the module
---
### [x] Task M3-2: Create _blender_import.py
- **File**: `render-worker/scripts/_blender_import.py` (NEW)
- **What**: Extract `_import_glb()` and `_apply_rotation()` into module. Rename to `import_glb()` / `apply_rotation()`.
- **Acceptance gate**: `grep -c "def _import_glb\|def _apply_rotation" render-worker/scripts/blender_render.py` → 0
- **Dependencies**: M1-4
- **Risk**: Low — no hidden globals beyond `bpy`, `math`, `Vector`
---
### [x] Task M3-3: Create _blender_materials.py
- **File**: `render-worker/scripts/_blender_materials.py` (NEW)
- **What**: Extract `_assign_failed_material()`, `_apply_material_library()`, and the `mat_map_lower` building loop. Consolidate the duplicated `mat_map_lower` logic (currently in Mode A and Mode B) into a single `build_mat_map_lower()` helper. `FAILED_MATERIAL_NAME` constant lives here.
- **Acceptance gate**: `grep -c "def _assign_failed_material\|def _apply_material_library" render-worker/scripts/blender_render.py` → 0
- **Dependencies**: M1-4
- **Risk**: Medium — `_apply_material_library()` currently uses `part_names_ordered` global; must convert to parameter
---
### [x] Task M3-4: Create _blender_camera.py
- **File**: `render-worker/scripts/_blender_camera.py` (NEW)
- **What**: Extract auto-camera placement block (bounding sphere computation, isometric positioning, clip plane setup, `ELEVATION_DEG`/`AZIMUTH_DEG` constants) and `setup_auto_lights()`.
- **Key signatures**: `def setup_auto_camera(parts, width, height) -> tuple[Vector, float]` (returns center + radius for reuse by lights); `def setup_auto_lights(bbox_center, bsphere_radius) -> None`
- **Acceptance gate**: `grep -c "ELEVATION_DEG\|AZIMUTH_DEG\|bsphere_radius" render-worker/scripts/blender_render.py` → 0
- **Dependencies**: M3-2
- **Risk**: Low — camera block is self-contained
---
### [x] Task M3-5: Create _blender_scene.py
- **File**: `render-worker/scripts/_blender_scene.py` (NEW)
- **What**: Extract `_ensure_collection()`, `_apply_smooth_batch()`, `_apply_sharp_edges_from_occ()`, shadow catcher setup into module.
- **Acceptance gate**: `grep -c "def _ensure_collection\|def _apply_smooth_batch\|def _apply_sharp_edges_from_occ" render-worker/scripts/blender_render.py` → 0
- **Dependencies**: M1-4
- **Risk**: Low
---
### [x] Task M3-6: Thin blender_render.py to entry-point
- **File**: `render-worker/scripts/blender_render.py`
- **What**: Replace all extracted function bodies with imports from submodules. Add `sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))` before imports so Blender Python finds the submodules. Result: argument parsing + Mode A/B orchestration + timing only. Target: < 200 lines.
- **Acceptance gate**: `wc -l render-worker/scripts/blender_render.py` → < 200; upload `81113-l_cut.stp` → thumbnail renders correctly
- **Dependencies**: M3-1, M3-2, M3-3, M3-4, M3-5
- **Risk**: High (integration step) — test immediately after deploy
---
## Migration Check
**No migration required.** `stl_quality` key stays in DB (harmless). No new columns or tables.
---
## Order Recommendation
```
M1-1 (delete dirs) → M1-4 (dead func blender) → M1-5 (dead func step_processor)
→ M1-2 (admin.py) → M1-3 (frontend)
→ M3-1..M3-5 (create submodules in parallel where possible)
→ M3-6 (thin blender_render.py — integration, highest risk, test immediately)
```
Deploy after M1: `docker compose up -d --build backend`
Deploy after M3-6: `docker compose up -d --build render-worker`
---
## Risks / Open Questions
1. **Blender `sys.path`**: Submodule files must be at `/render-scripts/` (the volume mount path). `sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))` is the safe way to ensure this regardless of CWD.
2. **`part_names_ordered` global**: Currently used across multiple functions in `blender_render.py`. Must be explicitly passed as a parameter to `apply_material_library()` in M3-3.
3. **M3 scope**: M3 is a pure refactor — no behaviour change. If time is limited, M1 (dead code removal) delivers clean value on its own. M3 can be deferred to a separate session.