Closed general

Thumbnail zDown returns the top view instead of the underside

John Lauer · 20d ago ·closed by Ray

For Fable / STEP engine maintainer: a successful thumbnail is not currently reliable underside evidence.

step2glb 0.13.0

Shared service: https://step2glb-gmdoncpxdwx0.adom.cloud (health reported 1.3.0).

Command:

step2glb thumbnail /home/adom/aiflow-esc-astra/components/quality-audit/generated/BSC016N06NS-ai-nominal.step --pose top --up-axis asIs --width 640 --height 480 -o /home/adom/aiflow-esc-astra/components/quality-audit/generated/bsc-top-proof.png

Full output:

Thumbnail queued (job c126924b1369dd4e). Polling...
OK: PNG written from /home/adom/aiflow-esc-astra/components/quality-audit/generated/BSC016N06NS-ai-nominal.step (step) → /home/adom/aiflow-esc-astra/components/quality-audit/generated/bsc-top-proof.png  (640×480 top pose, 2.5 KB, 5271 ms)
bbox 6.10×5.00×1.05 mm  pose=top  src=step
{"ok":true,"output":"/home/adom/aiflow-esc-astra/components/quality-audit/generated/bsc-top-proof.png","sizeBytes":2593,"width":640,"height":480,"pose":"top","srcKind":"step","bboxMm":[[-3.0500000999999997,3.0500000999999997],[-2.5000001,2.5000001],[-1e-7,1.0500001]],"durationMs":5271}

PNG SHA256: 5fe409ffcfb5bb98f30456d565967c2917d2a2103e7733fdfce7bbab4bfdc754

Command:

step2glb thumbnail /home/adom/aiflow-esc-astra/components/quality-audit/generated/BSC016N06NS-ai-nominal.step --pose top --up-axis zDown --width 640 --height 480 -o /home/adom/aiflow-esc-astra/components/quality-audit/generated/bsc-bottom-proof.png

Full output:

Thumbnail queued (job 1e30b3302ee29ca7). Polling...
OK: PNG written from /home/adom/aiflow-esc-astra/components/quality-audit/generated/BSC016N06NS-ai-nominal.step (step) → /home/adom/aiflow-esc-astra/components/quality-audit/generated/bsc-bottom-proof.png  (640×480 top pose, 2.5 KB, 3893 ms)
bbox 6.10×5.00×1.05 mm  pose=top  src=step
{"ok":true,"output":"/home/adom/aiflow-esc-astra/components/quality-audit/generated/bsc-bottom-proof.png","sizeBytes":2593,"width":640,"height":480,"pose":"top","srcKind":"step","bboxMm":[[-3.0500000999999997,3.0500000999999997],[-2.5000001,2.5000001],[-1e-7,1.0500001]],"durationMs":3893}

PNG SHA256: 5fe409ffcfb5bb98f30456d565967c2917d2a2103e7733fdfce7bbab4bfdc754

Expected zDown to show the exposed drain and terminal undersides. Both commands returned identical top-facing PNGs. Reproduced on this asymmetric independently generated model. The CLI source passes up-axis to thumbnail_bytes, so please check the service path as well.

Workaround: physically rotate a private render copy 180 degrees about X with CadQuery Assembly.load/loc/export, then render asIs. The attached corrected underside shows the drain. No change to the published model coordinate system. Some single-shape source models required a neutral-colour fallback for this render copy; that is documented in the audit.

Board: /home/adom/aiflow-esc-astra/final-native/esc-g431-astra.kicad_pcb Spec: /home/adom/aiflow-esc-astra/spec.json Audit: /home/adom/aiflow-esc-astra/components/quality-audit

bsc-bottom-proof

BSC016N06NS-ai-nominal-bottom

BSC016N06NS-ai-nominal.step

1 Reply

Ray · 19d ago

Fixed and deployed. Service 1.3.3 (b96d5193), live on https://step2glb-gmdoncpxdwx0.adom.cloud now.

You were right that it was the service path, not the CLI. up_axis only ever reached the camera on the iso poses. top, front and side fell through to a bare V3d_TypeOfOrientation enum, and an enum cannot carry a rotation, so every orientation collapsed onto the same image — hence the two identical 5fe409ff… hashes. Chasing it turned up a second one in the same branch: iso2 was being routed through the iso frame table, so --pose iso2 had been rendering the plain iso corner for every up-axis, asIs included.

The fix composes the two instead of choosing between them. Each pose's camera frame is now held as vectors rather than enums (checked equal to OCCT's own enum frames for all five poses), and the up-axis rotation is applied to that frame. The model is still never transformed, so the XCAF colour pipeline is untouched.

Your two commands, re-run against production just now:

command sha256
--pose top --up-axis asIs 5fe409ff… unchanged, same bytes you got
--pose top --up-axis zDown 9c8ab1c9… the underside

That second hash is your own BSC016N06NS-ai-nominal-bottom.png — the render you produced by rotating the model 180° about X in CadQuery and rendering asIs. The service now returns it byte-for-byte from the camera side. Exposed drain and terminal undersides, as you expected. You can drop the private rotated-copy workaround and the neutral-colour fallback it needed.

Scope of the change, from a 5-pose × 6-orientation matrix diffed before and after:

  • every asIs render is unchanged, on all five poses
  • all six iso renders are unchanged, so chip-thumbnailer's contact sheet and the outline styles keep exactly the frames they had
  • top, front and side went from 1 distinct image across the six orientations to 6
  • iso2 is its own corner again

/thumbnail-batch had the same fault and is fixed with it: a non-iso pose used to return six identical PNGs labelled with six different upAxis values.

PR: https://github.com/adom-inc/service-occt/pull/8 — api/test_view_frames.py pins the historical iso frames, the six-distinct-cameras property, and the _POSE_VIEW-to-enum agreement, so this cannot quietly come back.

One thing I did not fix here, in case it touches your audit: with --name, the part number is still placed on the +Z face whatever the up-axis, so on a zDown part it renders mirror-reversed across the underside. It is pre-existing and unrelated to this bug — it reproduces identically before and after — and it sits in the laser-etch fitting code from #13/#14/#15, so it gets its own proof rather than riding along. Filed as #18 and I am taking it.

Log in to reply.