diff --git a/LEARNINGS.md b/LEARNINGS.md index cbd7d0d..f8e5d5d 100644 --- a/LEARNINGS.md +++ b/LEARNINGS.md @@ -395,6 +395,16 @@ Für den `/plan`-Agent: alle relevanten System-Daten sind OHNE docker-Befehle zu - **Kein `docker exec backend python3 -c`** für Code-Exploration — dauert lang und braucht laufende Container - **MEMORY.md** enthält Container-Capabilities: OCP nur in `render-worker`, nicht in `worker` oder `backend` +### 2026-03-11 | Render-Pipeline | Production GLB: OCC custom_normal überschreibt Blender-Normalen +`export_step_to_gltf.py` (RWGltf_CafWriter) embedded per-corner normals from OCC tessellation as a `custom_normal` attribute (CORNER, INT16_2D) in the geometry GLB. Blender's glTF importer preserves this as a custom attribute. The glTF exporter then re-exports these pre-baked normals **unchanged**, ignoring `shade_smooth_by_angle` processing and explicit `edge.smooth=False` sharp marks — sharp edges are invisible in the production GLB. +**Lösung:** In `export_gltf.py` und `blender_render.py`: nach GLB-Import das `custom_normal`-Attribut von allen Mesh-Objekten entfernen, BEVOR `shade_smooth_by_angle()` aufgerufen wird. Dann berechnet Blender die Normalen neu aus den sharp-edge-Marks. +**Diagnose:** File-Size-Test: WITH custom_normal=1218960 Bytes, WITHOUT=1137944 Bytes. Re-import zeigte `has_custom_normals=True`. GLB-JSON-Inspektion mit `struct.unpack` + `json.loads` direkt auf `.glb`-Datei. +```python +for obj in mesh_objects: + if "custom_normal" in obj.data.attributes: + obj.data.attributes.remove(obj.data.attributes["custom_normal"]) +``` + --- ## Offene Fragen