Move OpenCASCADE out of the merged editor image into occ_service: a separate
emscripten module (-sASYNCIFY=0, MODULARIZE, in-container -Oz finalize, 2N+8
pre-warmed pthread pool) booted lazily in a dedicated Web Worker on the first
STEP export or STEP/IGES model parse. kicad_editor.wasm ~190 MB -> 130 MB;
sessions that never touch OCC never fetch its 57 MB. STEP export works in the
browser for the first time: the unchanged desktop dialog runs EXPORTER_STEP,
whose wasm shadow suspends into globalThis.occService and the export bytes go
straight to a browser download (never entering the editor heap). STEP/IGES 3D
models parse in the worker via the oce shadow (S3D WriteCache/ReadCache wire).
- wasm/occ-service/: service CMake target (hooked from the kicad fork's
top-level CMakeLists, wasm/editor pattern), embind entry
(occExport/occLoadModel), wxConfig pre-js.
- wasm/stubs/{exporter_step,oce_plugin}_stub.cpp: EM_ASYNC_JS worker bridges
(callee-shadowing; no caller #ifdefs).
- web/standalone: provider installed whenever the kicad_editor bundle boots
(cross-face safe); ONE shared worker-boot source occ-worker.js (vite ?raw;
the e2e stub reads the same file) — blob worker with locateFile absolutized
against the glue URL; export download-name guard.
- deps: OCC builds with RapidJSON so its glTF/GLB writer exists — pinned to
the vcpkg master snapshot 2025-02-26 (24b5e7a8b27f), the same code official
KiCad consumes via vcpkg.json's opencascade[rapidjson]; rapidjson's latest
tag (v1.1.0, 2016) is ill-formed under modern clang.
- tests: occ-export dialog e2e (lazy-fetch boundary + STEP download bytes),
occ-probe incl. a 9-format matrix (step/stpz/brep/xao/ply/stl/glb/u3d/pdf),
3d-viewer-models hard-asserts the worker parse; occ provider stub installed
ambiently by the kicad fixtures.
Validated against desktop kicad-cli 10.0.4: geometric exact equality (bbox
delta 0 um, volume delta 0.0000%) for STEP/GLB/STL/BREP/STPZ across three
boards and option sweeps — with desktop OCC 7.9 vs wasm OCC 7.8; PLY/XAO/PDF
structurally equal; U3D same-size (quantizer float LSBs differ). Full kicad
e2e green on Firefox and Chromium; standalone verified end to end (lazy fetch
only on the Export click; export.step 60,628 B ISO-10303-21; loadModel 700 KB
STEP -> 569 KB scenegraph cache).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Provides wasm/stubs/model_substitution_stub.cpp — no-op IsWrlExtension /
STEP_CATALOG::Build / FindMatchFor — so pcbnew and footprint_editor link when the
3D viewer is off (KICAD_BUILD_3D_VIEWER_WASM=OFF). The KiCad 10 rebase made
dialog_migrate_3d_models.cpp reference these, which live in the unlinked 3D
library. The browser build has no 3D viewer, so model migration finds no
substitutions. Bumps kicad to the matching CMake wiring (fef0343).
Verified: pcbnew + footprint_editor compile and link clean (eeschema/symbol_editor
unaffected).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Brings up KiCad's pagelayout_editor (drawing-sheet editor) in the
browser, to roughly the same "boots, canvas visible, partially usable
in-session" level as the existing pcbnew/eeschema/calculator ports.
Build:
- docker/build.sh: add pl_editor to the unified app dispatch (case,
subdir map, all-loop).
- scripts/kicad/build-kicad-target.sh: add pl_editor to the case;
upstream target name pl_editor under source subdir pagelayout_editor.
- scripts/kicad/build-pl_editor.sh: 7-line thin wrapper matching the
pcbnew/eeschema/calculator pattern.
- tests/scripts/setup-kicad-wasm.sh: copy_app pl_editor.
App glue:
- wasm/stubs/nl_pl_editor_plugin_stub.cpp: no-op SpaceMouse plugin so
pl_editor_frame.cpp's NL_PL_EDITOR_PLUGIN symbols resolve. Mirrors
nl_pcbnew_plugin_stub.cpp.
- tests/apps/kicad/pl_editor.html: browser shell. preRun creates
/home/kicad and FS.chdir there so file dialogs land somewhere
friendly instead of MEMFS root (/dev/, /proc/, etc.).
E2E coverage:
- tests/kicad/pl_editor.spec.ts: 5 tests — smoke (canvas, no abort),
wizard, File menu has Open/Save As, file-dialog folder-navigation
regression, canvas + toolbar metrics.
- tests/e2e/filedialog-folder-nav.spec.ts: wxWidgets-level twin of
the regression test (exercises the underlying widget directly via
the standalone filedialog_test app).
Submodule bumps:
- kicad → feature/pl-editor (WASM gating in pagelayout_editor's
CMakeLists + navlib stub).
- wxwidgets → feature/pl-editor (wxGenericFileDialog::OnOk navigates
into selected directories; wasm/mouse.cpp emits wxEVT_LEFT_DCLICK
via timestamp-based double-click detection — the latter benefits
every wxWidgets-WASM app).
See features/pl-editor/ for the design doc + per-repo diff patches.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Set KICAD_BUILD_3D_VIEWER_WASM=OFF in build script
- Add comprehensive 3D canvas stubs (~500 lines) including:
- EDA_3D_CANVAS with wxWidgets event table
- BOARD_ADAPTER, EDA_3D_VIEWER_SETTINGS
- PANEL_PREVIEW_3D_MODEL with all event handlers
- DIALOG_SELECT_3DMODEL
- TRACK_BALL camera
- BBOX_2D, BBOX_3D, BVH_CONTAINER_2D
- OGL_ATT_LIST::GetAttributesList
- Add 3D scenegraph stubs for VRML export
- Update KiCad submodule with WASM guards
- Update WebGL GAL implementation plan to COMPLETE status
All 4 phases of the WebGL GAL implementation are now complete:
- Phase 1: Native test harness (28 scenarios)
- Phase 2: WebGL GAL implementation (~27,800 lines)
- Phase 3: Complete API coverage
- Phase 4: KiCad integration with 3D viewer stubs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The idftools/vrml_layer.cpp uses this GLU tessellation constant
which was missing from our WASM GLU stub header.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes:
- Add glu_wasm_impl.cpp: GLU tesselator using KiCad's earcut triangulation
- Add GL/glu.h: GLU header for WASM builds
- Add 3D viewer stubs for KICAD_BUILD_3D_VIEWER_WASM=ON
- Remove obsolete gl_canvas_stub.cpp (OpenGL now uses real impl)
- Remove obsolete glu_stub.c (replaced by glu_wasm_impl.cpp)
- Update build-pcbnew.sh comment about GLU implementation
The OpenGL GAL now works in WASM using WebGL with LEGACY_GL_EMULATION.
3D viewer is stubbed out but builds successfully.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Build improvements:
- Change -O0 to -O1 to fix "local count too large" asyncify error
- Add wasm-emscripten-finalize to host (Docker OOMs on large WASM)
- Use -gseparate-dwarf for smaller main binary with debug info
- Build native protoc for code generation
- Add more functions to asyncify removelist
Runtime fixes:
- Add inject-dyncall-shims.sh to fix "dynCall_* is not defined" in Emscripten 4.x
- Update wxwidgets with browserInfo.name fix
New stubs and bindings:
- Add Embind bindings for JavaScript interop
- Add stubs for scripting, API plugin, PCB frame, navlib
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Build the 3D viewer code for WASM instead of stubbing it out.
This is simpler to maintain than complex header stubs.
Changes:
- Enable KICAD_BUILD_3D_VIEWER_WASM=ON in build script
- Remove -gsource-map to avoid OOM in wasm-emscripten-finalize
- Add OpenGL stubs for fixed-function pipeline (WebGL ES 2.0 only)
- Add GLU stub for gluErrorString
- Add NNG stub for IPC API (sockets don't work in WASM)
- Add PCBnew scripting stub
- Expand curl and libgit2 stubs
The 3D viewer code compiles but won't render at runtime since
OpenGL GAL is disabled and Cairo GAL is used instead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>