Closed bug report

`--render-board` clobbers generated artifacts: board GLB is Y-up with no up-axis stamp, and render/manifest.json is rewritten wholesale

barrett-land · 3mo ago ·closed by barrett-land

--render-board rewrites generated artifacts wholesale, so anything a downstream tool or a human added is silently destroyed on the next publish. Hit both halves of this on adom/usb3-to-ethernet-dataonly-molecule today; commit 962e00bf ("render assets + archive v1.3.0") reverted two separate fixes that had been pushed ~18 minutes earlier.

Related: #3 (STEP → step2glb), #5 (merge-safe package.json), #9 (version-aware archive), #4 (emit render assets).


Problem 1 — the emitted board GLB is Y-up and carries no up-axis stamp

render/board.glb for this molecule is a kicad-cli export. Its own metadata says so:

asset.extras.adom.generator          = "service-kicad 08def5a7"
asset.extras.adom.provenanceWarning  = "Exported by kicad-cli via service-kicad, NOT the
                                        molecule pipeline: no MP-marker anchoring, gold
                                        machine-pin material, meter normalization, or
                                        footprint emit. For molecule use, export STEP here
                                        and convert with step2glb/service-occt."

kicad-cli emits glTF-standard Y-up. Walking the node tree with transforms applied:

X Y Z thin axis
as published 40.0 27.25 40.0 Y

Two consumers disagree about what that means, and both are currently wrong for this file:

  • Wiki 3D viewer hard-codes zUp: true and applies its own −90° X. Given a Y-up model it double-rotates → the board renders on its side on the wiki page.
  • adom-project-manager reads asset.extras.adomMolecule.upAxis (glb_up_axis() in src/main.rs) and applies orientation="0deg -90deg 0deg" only when it reads "z". A kicad-cli GLB has no such stamp → up_axis: null → no rotation applied.

So there is no single orientation that satisfies both unless the file is Z-up AND stamped. Rotating alone fixes the wiki and breaks APM; stamping alone fixes nothing.

Ask

Either:

  1. Route board GLBs through STEP → step2glb as #3 proposes (preferred — also fixes the machine-pin material, meter normalization and MP-marker anchoring the provenance warning lists), or
  2. If kicad-cli stays the source for board mode, rotate to Z-up and stamp asset.extras.adomMolecule.upAxis = "z" on emit, so every consumer keys off the declared axis instead of guessing.

Whichever path, the invariant worth stating explicitly in the pipeline: every emitted GLB declares its up-axis. A consumer should never have to infer orientation from geometry.

Current workaround (will be clobbered again)

render/board.glb has been hand-patched: root wrapped in a +90° X node and adomMolecule.upAxis = "z" stamped. Verified thin axis is now Z, wiki viewer renders flat, and APM reports up_axis: "z". The next --render-board will overwrite it. Note render/1.3.0/board.glb is still the unpatched Y-up copy, so APM's ?v=1.3.0 still shows it sideways.


Problem 2 — render/manifest.json is rewritten from scratch, dropping unknown keys

The manifest is regenerated wholesale rather than merged, so any key the pipeline doesn't itself author is lost.

Concretely: interactive viewer exports (adom-layout-viewer embed / adom-schematic-viewer embed) were archived per board version under viewers/<version>/, and advertised in the manifest so APM can serve the viewer matching the version it is displaying:

{
  "viewers": ["layout", "sch-usb", "sch-data", "sch-ethernet", "sch-power"],
  "viewers_path": "viewers/{version}/",
  "versions": [ { "version": "1.3.0", "viewers": [ ... ] } ]
}

After 962e00bf the manifest was back to ["current","glb","pcb","sheets","v","versions"] — top-level viewers/viewers_path gone, and versions[].viewers gone from the current entry. (The viewers/*.html files themselves survived, because the pipeline doesn't know that directory exists — only the manifest describing them was lost, which is arguably worse: the assets are present but undiscoverable.)

Ask

Make the manifest write merge-safe, exactly as #5 asks for package.json: read the existing render/manifest.json, update only the keys the pipeline owns (current, glb, pcb, sheets, v, versions[].{glb,pcb,sheets,hash,version}), and preserve everything else — including unknown keys on versions[] entries.

That single change makes render/ safely extensible by downstream tools instead of a pipeline-exclusive directory.


Why this matters beyond one board

Both problems have the same shape: --render-board treats render/ as write-only territory it fully owns. Any consumer that wants to enrich a board's published assets (APM's version selector, the interactive viewers, future per-version artifacts) has no durable place to put anything. Every publish silently resets it, with no warning and no diff.

Suggested acceptance

  • Board GLBs declare their up-axis (asset.extras.adomMolecule.upAxis) on every emit, whether produced via step2glb (#3) or kicad-cli
  • Wiki 3D viewer and APM both render a pipeline-published board flat, with no hand-patching
  • render/manifest.json writes are merge-safe; unknown top-level and per-version keys survive a re-render
  • Re-running --render-board on adom/usb3-to-ethernet-dataonly-molecule leaves viewers/viewers_path and the GLB orientation intact
  • Decide whether archiving interactive viewers per version belongs in the pipeline itself (ties into #9)

2 Replies

Drew Owens · 3mo ago

Triage + ownership split (page is mine, the emitting tool isn't):

Pipeline side — done tonight (molecule-pipeline 1.1.2): your invariant is now stated verbatim in the pipeline invariants: every emitted GLB declares its up-axis; a consumer never infers orientation from geometry — with this issue cited as the failure case.

The two mechanical fixes are APM-side (--render-board is the writer for both):

  1. Board GLB Y-up/unstamped: of your two options I'd push for option 1 (route through STEP → step2glb) — it also picks up meter normalization + provenance stamping for free, and step2glb now has a compress= override (#4, shipped) if render copies want different compression. Option 2 (rotate+stamp at emit) is fine as a stopgap and much smaller.
  2. render/manifest.json rewritten wholesale, dropping unknown keys (your viewers/ entries): that's the same merge-safe discipline you specced for versions[] in #9 — unknown keys should survive a rewrite. Also APM's manifest writer.

Flagging both to Barrett as the --render-board owner (this issue is on his radar via the #164 thread). Pipeline docs are done; nothing else actionable on the molecule-publish side. — Drew's agent

barrett-land · 3mo ago

Resolved — shipped in adom/adom-project-manager v0.6.3.

Both halves were fixed in --render-board (APM-side, as triaged):

Problem 1 (board GLB Y-up + unstamped): new finalize_board_glb() optimizes the raw glb-package export and guarantees it is Z-up + asset.extras.adomMolecule.upAxis = "z" — via the (previously dead-code) glb_optimize.mjs +90°X rotation, now wired in and stamping, with a self-contained Rust ensure_zup_stamp() fallback when node/gltf-transform aren't present. Both consumers now render flat with no hand-patching.

Problem 2 (manifest rewritten wholesale): new pure merge_render_manifest() starts from the existing manifest and overwrites only pipeline-owned keys — unknown top-level keys (viewers, viewers_path) and unknown per-version keys now survive a re-render.

Verified live (Z-up + stamped, all components, manifest merge-safe): adom/usb3-to-ethernet-dataonly-molecule, adom/adom-machine-pins-fusion-lbr, drew2/taprite-solonoid-wiretest. 7 unit tests cover rotate/stamp/idempotency and manifest key-preservation.

On the STEP → step2glb route (your preferred option 1 / #3): it's blocked server-side for APM — service-kicad has no step-package endpoint, so a plain /step export drops a board's custom .3dshapes models (confirmed: the usb3 board lost its LAN7800 / HD3SS3212 / RJ45 / crystal / Würth parts). Option 2 (rotate + stamp the glb-package output) was taken because it meets every acceptance item and keeps all components. The STEP path's extra benefits (meter-normalization, gold pins) remain gated on a service-kicad step-package endpoint — tracking under #3.

Log in to reply.