# Plan: P1 Remaining Cleanup — M1 Dead Code + M3 blender_render.py Split ## Context Three categories of cleanup: 1. **M1a**: Two legacy HTTP renderer directories (`blender-renderer/`, `threejs-renderer/`) still exist in repo root despite the services being removed in Phase A. 2. **M1b**: Dead code in backend services — PIL fallback in `step_processor.py`, `stl_quality` param (always "low") in `render_blender.py` and `domains/rendering/tasks.py`. 3. **M3**: `render-worker/scripts/blender_render.py` is 263 lines (target < 80) — argparse, scene setup, and render config should move to submodules. `domains/rendering/tasks.py` is **NOT dead code** — contains 6 active Celery tasks (`render_still_task`, `render_turntable_task`, `render_order_line_still_task`, `export_gltf_for_order_line_task`, `export_blend_for_order_line_task`, `apply_asset_library_materials_task`). Only the `stl_quality` param needs removal. ## Affected Files - `blender-renderer/` — delete entire directory - `threejs-renderer/` — delete entire directory - `backend/app/services/step_processor.py` — remove PIL fallback block (~line 565) - `backend/app/services/render_blender.py` — remove `stl_quality` param from `_glb_from_step()`, `render_still()`, `render_turntable_to_file()` - `backend/app/domains/rendering/tasks.py` — remove `stl_quality` param from `render_still_task`, `render_turntable_task` - `render-worker/scripts/blender_render.py` — thin to < 80 lines - `render-worker/scripts/_blender_args.py` — new file (argument parsing) - `render-worker/scripts/_blender_scene_setup.py` — new file (MODE A/B scene setup) - `render-worker/scripts/_blender_render_config.py` — new file (engine + output config) ## Tasks (in order) ### [x] Task 1: Delete legacy renderer directories - **File**: `blender-renderer/`, `threejs-renderer/` (repo root) - **What**: `git rm -rf blender-renderer/ threejs-renderer/` — removes both legacy HTTP service directories superseded by the Celery render-worker in Phase A - **Acceptance gate**: `ls blender-renderer/ threejs-renderer/` both return "no such file or directory" - **Dependencies**: none - **Risk**: Low — not imported by any active pipeline code ### [x] Task 2: Remove PIL fallback from step_processor.py - **File**: `backend/app/services/step_processor.py` - **What**: Find `from PIL import Image` (~line 565, inside `_generate_thumbnail()`) and the PIL thumbnail generation conditional branch. Remove the import and the branch — leave only the render-worker path. - **Acceptance gate**: `grep -n "PIL\|Pillow" backend/app/services/step_processor.py` returns nothing - **Dependencies**: none - **Risk**: Low — PIL path unreachable; render-worker handles all thumbnails ### [x] Task 3: Remove stl_quality param from render_blender.py - **File**: `backend/app/services/render_blender.py` - **What**: - `_glb_from_step(step_path, output_dir, quality="low")` → `_glb_from_step(step_path, output_dir)` — hardcode the low-quality deflection values inline (no conditional on quality) - Remove `stl_quality: str = "low"` from `render_still(...)` and `render_turntable_to_file(...)` - Remove all internal `quality=stl_quality` pass-throughs - **Acceptance gate**: `grep -n "stl_quality" backend/app/services/render_blender.py` returns nothing - **Dependencies**: none (Task 4 updates callers) - **Risk**: Medium — callers in tasks.py pass `stl_quality`; update in Task 4 immediately after ### [x] Task 4: Remove stl_quality param from domains/rendering/tasks.py - **File**: `backend/app/domains/rendering/tasks.py` - **What**: - `render_still_task` (~line 48): remove `stl_quality: str = "low"` from signature and from the `render_still(...)` call - `render_turntable_task` (~line 152): remove `stl_quality: str = "low"` from signature. Lines ~210–228 inline OCC GLB generation reads `stl_quality` to choose deflection values — replace hardcoded quality-based values with DB settings reads (`scene_linear_deflection`, `scene_angular_deflection`). Pattern to follow: `export_glb.py` reads these settings via `sys_settings.get("scene_linear_deflection", 0.03)`. - **Acceptance gate**: `grep -n "stl_quality" backend/app/domains/rendering/tasks.py` returns nothing - **Dependencies**: Task 3 - **Risk**: Medium — inline tessellation block must correctly read DB settings; verify key names match migration 062 output ### [x] Task 5: Extract _blender_args.py - **File**: `render-worker/scripts/blender_render.py`, new `render-worker/scripts/_blender_args.py` - **What**: Move the `argparse` block (lines ~44–110, ~67 lines) into `_blender_args.py` as a `parse_args()` function. `blender_render.py` calls `from _blender_args import parse_args` and uses `args = parse_args()`. - **Acceptance gate**: `_blender_args.py` exists with the parser; `blender_render.py` line count drops by ~60 - **Dependencies**: none - **Risk**: Low — pure refactor, no logic change ### [x] Task 6: Extract _blender_scene_setup.py - **File**: `render-worker/scripts/blender_render.py`, new `render-worker/scripts/_blender_scene_setup.py` - **What**: Move the MODE A / MODE B scene setup branches (lines ~131–214, ~84 lines) into `_blender_scene_setup.py` as `setup_scene(args, scene)` (dispatches internally to mode A or B based on `args.blend_template`). Import and call in `blender_render.py`. - **Acceptance gate**: `_blender_scene_setup.py` exists; `blender_render.py` line count drops by ~80 - **Dependencies**: Task 5 - **Risk**: Low — pure refactor; `bpy` available in Blender Python context ### [x] Task 7: Extract _blender_render_config.py and verify ≤ 80 lines - **File**: `render-worker/scripts/blender_render.py`, new `render-worker/scripts/_blender_render_config.py` - **What**: Move engine/render settings + output path logic (lines ~216–258, ~43 lines) into `_blender_render_config.py` as `configure_render(scene, args, output_path, gpu_type)`. After extraction, `blender_render.py` must be ≤ 80 lines. - **Acceptance gate**: `wc -l render-worker/scripts/blender_render.py` shows ≤ 80 - **Dependencies**: Task 6 - **Risk**: Low — pure refactor ## Migration Check No new Alembic migration required. Task 4 reads existing keys (`scene_linear_deflection`, `scene_angular_deflection`) from the `system_settings` table, already present after migration 062. ## Order Recommendation Tasks 1 and 2 are independent — can run in parallel. Tasks 3 and 4 are coupled — run 3 immediately before 4. Tasks 5, 6, 7 are sequential — each further reduces blender_render.py line count. ## Risks / Open Questions - `render_turntable_task` inline tessellation: confirm exact key names are `scene_linear_deflection` / `scene_angular_deflection` (not the old `gltf_preview_*` names) by reading `export_glb.py` before Task 4. - After Task 7, do a smoke-test render to confirm submodule imports work inside Blender's Python interpreter.