4.7 KiB
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,
plus `pieces` (which triangles are which fin, for a host that
shows one object per fin), `overFaces` and `smallFaces` (the
faces the site paints red, and amber: too small to fin)
engine/draw_entry.js Draw mode: the same soup + two points -> one hand-drawn wall
(web/draw.js drawnWall, called the way the site calls it)
engine/seat.js what both entries do first: centre + snap the part, set the
clearances -- so a wall doesn't move with plate position
engine/bridge.js base64 in/out for Python hosts running the bundle in V8 (mini-racer)
engine/options.json the settings every plugin dialog is built from: key, type, default,
range or choices, label, tooltip, section, when it shows. Defaults,
ranges and choices are pinned to the website's controls (web/index.html)
by tests/options.test.js; fins_entry.js takes its defaults from it.
A host builds its dialog from it and passes the values through
optionsFromDialog() (and optionVisible() for show/hide; from Python,
host_options / host_visible), never by hand
engine/report.js the one-line result (walls, tines, overhangs not reached, floating
pieces) for JS hosts (the CLI); Python hosts' host_report says
the same words
vendor.py mini-racer vendored into a plugin folder, per platform, for hosts
that can't pip-install (Cura, FreeCAD): their build.py uses it
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; host_compute_pieces adds the
per-fin pieces and overhang faces; host_draw_wall draws one wall);
a settings dialog's values to
engine options (host_schema, host_options, host_visible). 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), Cura and FreeCAD (ship the bundle and the Python host next to the plugin), and Blender (the same, with mini-racer as a wheel Blender installs; it uses the per-fin pieces and drawWall), and Rhino (the same, with mini-racer pip-installed by Rhino 8 itself). 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.