The entry sends the full clearance set on every call, as the site's worker does: buildFins keeps it as module state and a plugin's V8 context lives across calls, so a partial set would leak PETG into the next PLA run. Unknown values throw instead of silently building PLA. Sway braces take the material's gap and bite.
Support Fins — shared plugin code
Code every plugin that can run JavaScript shares, so they all run the website's
engine (web/*.js), unmodified, instead of keeping their own copy of the geometry.
A fix on the site reaches a plugin the next time it is built.
engine/fins_entry.js posed triangle soup in (mm, z up) -> fin + bed-pad triangles out
engine/bridge.js base64 in/out for Python hosts running the bundle in V8 (mini-racer)
bundle.py esbuild: bridge.js + web/*.js -> one IIFE, global SupportFinsEngine
py/supportfins_host.py Python side for plugins that run the bundle in mini-racer: start V8
(host_engine), run the engine on a soup and map the fins back to
the caller's frame (host_compute). Orca inlines it at build time
py/supportfins_slice.py mesh -> per-layer polygons (split_shells, slice_soup, group_loops),
for hosts whose API takes layer polygons, not a mesh. Pure numpy.
Orca inlines it at build time
tests/ Deno tests: same fins as the website, anywhere on the plate;
the base64 bridge round-trips exactly
ENGINE-SENSITIVITY.md engine note: tine placement moves under 1e-13 mm of noise, and
how fins_entry.js neutralises it
python3 plugins/shared/bundle.py out.js # needs esbuild (npx fetches it on demand)
deno test --allow-read plugins/shared/tests/
python3 -m pytest -q plugins/shared/py/tests/ # needs numpy, trimesh, mini-racer==0.14.1
What goes where. Anything two plugins could use lives here: engine host, mesh
slicing, and next the options every dialog is built from. plugins/<host>/ only calls
into that host's API (read the part, show a dialog, add the result). A plugin that
needs a new piece of geometry adds it here, with its own tests, instead of in its
adapter. Fusion is the exception: its fins_core/ is pure Python because Fusion has no
numpy, and moves here only when another plugin wants per-fin objects.
Used by: Orca (inlines the bundle into its single-file plugin) and Cura (ships the bundle and the Python host next to the plugin). Onshape (FeatureScript) and Prusa (Lua) can't run JavaScript, so they don't use this.
CI: .github/workflows/plugins.yml rebuilds and tests
the plugins on every PR and push that touches web/ or plugins/, and on main publishes
the builds to the plugins-latest
pre-release.