read-only-viewer 0003: no lib catalog for viewers; 3D viewer from the session menu

- kicadShow3DViewer embind (pcbnew-only name, registered in the unguarded
  section so the merged kicad_editor image carries it): runOnCoroutine →
  ACTIONS::show3DViewer.
- Session menu: "3D viewer" row (pcbnew) — the only 3D entry once the wx
  chrome is hidden. Runs the deferred model prescan first.
- Read-only sessions: skip the boot-time enableRealtime scope-room socket
  (would 401 for non-members) and defer the board's 3D-model prescan until
  the viewer is opened (deferBoardModelPrescan / runDeferredModelPrescan).
- kicad submodule → read-only allowlist for the 3D viewer actions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXCntRWNn89M72EkrqMkvc
This commit is contained in:
Gergő Törcsvári 2026-08-27 15:26:30 +02:00
commit 97d4f9657e
No known key found for this signature in database
GPG key ID: 8E75F2CDE64E5322
8 changed files with 152 additions and 6 deletions

View file

@ -1898,6 +1898,23 @@ void pcbCollabFitViewport( double aCx, double aCy, double aHalfW, double aHalfH
presenceCore().fitViewport( aCx, aCy, aHalfW, aHalfH );
}
// JS → C++: open the board's 3D viewer (read-only-viewer / hide-UI sessions have
// no wx View menu). Dispatched like a native edit — CallAfter + COROUTINE via
// runOnCoroutine — so the tool runs on its own stack, where the 3D frame's
// RunMainStack bounce (the 8/12 sleep-park fix) is valid; never from inside a
// parked bridge crossing. Returns false when no board frame is up.
bool pcbShow3DViewer()
{
PCB_EDIT_FRAME* fr = pcbFrame();
if( !fr )
return false;
pcbjam_collab::runOnCoroutine(
fr, [fr]() { fr->GetToolManager()->RunAction( ACTIONS::show3DViewer ); } );
return true;
}
// JS pull of the current viewport transform (world↔screen mapping for the DOM layer):
// `{cx,cy,scale,w,h}` — world center, pixels-per-IU scale, canvas size in px.
std::string pcbCollabGetViewport()
@ -2795,6 +2812,9 @@ EMSCRIPTEN_BINDINGS(pcbnew) {
function("kicadLayersGetState", &pcbLayersGetState);
function("kicadLayersSetVisible", &pcbLayersSetVisible);
function("kicadLayersSetActive", &pcbLayersSetActive);
// Session-menu 3D entry (read-only-viewer 0003) — pcbnew-only name,
// merged-image safe (false when no board frame is up).
function("kicadShow3DViewer", &pcbShow3DViewer);
// pcbnew-only test helper (no eeschema counterpart — name is not shared).
function("kicadCollabTestItemBlob", &kicadCollabTestItemBlob);
// pcbnew-only ysync-review repro hooks (names not shared with eeschema).