Files
HartOMat/plan.md
T
Hartmut 3eba7b2d37 fix(glb): remove invalid export_colors param + fix viewer stale mesh
4 root causes fixed:

1. export_colors=False was removed in Blender 4.x — caused every Blender
   export to fail (exit 1) and always fall back to trimesh. Remove it.
   Blender now runs the full pipeline: materials + sharp edges.

2. GlbModel cloned ref never reset on url change — key={glbBlobUrl} forces
   React to remount GlbModel on each new blob URL, resetting the ref so
   fresh geometry is always loaded.

3. glbBlobUrl not cleared before re-fetch — setGlbBlobUrl(null) added at
   start of downloadUrl effect so spinner shows instead of stale mesh.

4. staleTime: 30_000 delayed picking up new MediaAsset after generation.
   Changed to staleTime: 0 so invalidation always triggers immediate refetch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 15:46:42 +01:00

4.1 KiB

Plan: Fix GLB Export Pipeline + Viewer Staleness

Root Cause Analysis

Bug 1 — export_colors not valid in Blender 5.0 (CRITICAL)

File: render-worker/scripts/export_gltf.py bpy.ops.export_scene.gltf(export_colors=False) → Blender exits code 1: keyword "export_colors" unrecognized → Blender path always fails → always falls back to trimesh → no materials, no sharp edges, faceted mesh. This is confirmed in every single log entry. Blender has never successfully exported a GLB.

Bug 2 — GlbModel cloned ref never resets on URL change (CRITICAL)

File: frontend/src/components/cad/InlineCadViewer.tsx cloned = useRef<THREE.Group | null>(null) with guard if (!cloned.current) only clones once. When glbBlobUrl changes (new GLB generated), React does NOT remount GlbModel (same position in tree), so cloned.current still holds the old geometry → old mesh shown forever. Fix: add key={glbBlobUrl} to <GlbModel> → forces remount on each new URL.

Bug 3 — glbBlobUrl not cleared between fetches (UX)

File: frontend/src/components/cad/InlineCadViewer.tsx When downloadUrl changes, cleanup revokes the old blob URL, but glbBlobUrl state still holds the (now revoked) old URL → GlbModel tries to render a revoked URL for the duration of the new fetch. Fix: setGlbBlobUrl(null) at the start of the effect before fetching.

Bug 4 — staleTime: 30_000 delays detecting new GLB (UX)

File: frontend/src/components/cad/InlineCadViewer.tsx After "Generate GLB" the task completes and a new MediaAsset is written to DB, but the assets query is cached for 30 seconds → downloadUrl stays stale → viewer fetches old GLB. Fix: reduce staleTime to 0 so the query always refetches on focus/mount after invalidation.


Affected Files

File Change Bug
render-worker/scripts/export_gltf.py Remove invalid export_colors=False 1
frontend/src/components/cad/InlineCadViewer.tsx key={glbBlobUrl} on GlbModel + clear state + staleTime=0 2, 3, 4

Tasks

Task 1: Fix Blender GLTF export parameters

File: render-worker/scripts/export_gltf.py Remove export_colors=False from bpy.ops.export_scene.gltf() call. Keep export_materials="EXPORT" and export_image_format="AUTO" — these are valid in Blender 5.0. Acceptance: Blender exits 0, GLB file is created with materials. Requires rebuild: yes — scripts are COPY'd into container.

Task 2: Fix GlbModel stale mesh on regeneration

File: frontend/src/components/cad/InlineCadViewer.tsx Add key={glbBlobUrl} on the <GlbModel> element inside the Canvas. This forces React to unmount+remount GlbModel whenever the blob URL changes, resetting the cloned ref and loading the fresh geometry. Acceptance: After generating a new GLB, the viewer shows the new mesh, not the old one.

Task 3: Clear stale blob URL before new fetch

File: frontend/src/components/cad/InlineCadViewer.tsx At the top of the useEffect([downloadUrl, token]) body, add setGlbBlobUrl(null) before the fetch. This shows the loading spinner instead of a broken/stale model during re-fetch. Acceptance: After regeneration, viewer shows spinner while new GLB loads.

Task 4: Remove staleTime delay on asset query

File: frontend/src/components/cad/InlineCadViewer.tsx Change staleTime: 30_000staleTime: 0 on the gltf_geometry assets query. The qc.invalidateQueries() call after generating already forces a refetch, but staleTime=0 also ensures refetch on window focus/tab return. Acceptance: New MediaAsset is picked up within seconds of task completion.


Reihenfolge

Task 1 (rebuild) + Tasks 2/3/4 (frontend hot-reload) in parallel.

Risiken

  • export_materials="EXPORT" and export_image_format="AUTO" may also be invalid in Blender 5.0. If so, remove them too and test with bare minimum params (format + apply only).
  • If the Schaeffler .blend library materials use custom node groups instead of Principled BSDF, the GLTF exporter will still export flat grey — that requires material baking, out of scope here.