Skip to content

Gridfinity: open a bin on any side, with no wall and no stacking lip there, so bins side by side make one run (#682) - #725

Merged
henmedia merged 1 commit into
henmedia:mainfrom
mlugo-apx:gridfinity-open-sides
Oct 22, 2026
Merged

henmedia merged 1 commit into
henmedia:mainfrom
mlugo-apx:gridfinity-open-sides

Conversation

@mlugo-apx

Copy link
Copy Markdown
Contributor

For #682, open sides for Gridfinity bins as you described them there: a switch per side that takes away that wall and its stacking lip, so open bins side by side make one continuous run.

Summary

  • A Gridfinity bin has four new switches under Properties, after Floor height: Open at the back, Open at the front, Open on the left and Open on the right. They are off until set, so every bin and every saved file builds as before. Any combination works; with all four the bin is a tray, a floor on its feet.
  • An open side has no wall and no stacking lip above the floor. The walls beside it and their lip run straight out to the bin's outline and end square, so two open bins side by side are 0.5 mm apart, as any two bins are. The floor runs flat out to the edge and ends square there, also in a bin with finger scoops, whose other floor edges are rounded. The feet and the magnet holes are not touched.
  • A label shelf or finger scoop set on an open side is not built and its switch is hidden; the setting is kept for when the side is closed again. The scoops repeated against the dividers facing that way go with it (see Notes), and a bin whose only scoop is on an open side loses the 2.8 mm rounding of its whole floor, as a bin without scoops has none.
  • Shelves and scoops on the walls beside an open side, and dividers that meet it, run out to the edge. A compartment against an open side is not offered a label shelf there; one already chosen there is left out, with a note under Label shelf in the compartments card.
  • A bin without the lip whose floor is raised to the top is a solid block and shows no switches; a baseplate has none either.
  • A bin stacked on an open bin is held by the lip on its closed sides only, so nothing stacks on a tray. The guide says so, and that open sides are not part of the specification.
  • The bin stays an exact body, so the edge tool and the STEP export keep working on it (see Notes for two fillets that do not).
  • MCP: layerling_create_shape and layerling_update_object take gridfinityOpenBack, gridfinityOpenFront, gridfinityOpenLeft and gridfinityOpenRight, and layerling_read_scene reports them. No new action.
  • The switches are saved as shape settings like the bin's other values.

How it is built

  • lib/gridfinityGeometry.ts: gridfinityPlan gets open, false on every side of a solid block or a baseplate (openFits). roundedLoop takes the open sides: they stay on the outline at every inset, the corners they touch are square, and each point on a side says which side it is. The display mesh sweeps the wall along each run of closed sides only (openBin), closes the wall's end in the open side's plane together with the floor's edge, and caps the floor out to the outline. gridfinityOpenGrown and gridfinityOpenCorners are the two small helpers both kernels use.
  • The inside's cutter and each compartment's run on through an open side by GRIDFINITY_OPEN_REACH (the 3.75 mm corner plus 2 mm), so their corner roundings and the floor's rounding lie beyond the outline, where there is no bin. In the labelled mesh the shelves, scoops and dividers are cut to that grown inside and then cut off 0.001 mm inside the outline (LABEL_OPEN_TRIM): cut exactly at it, a piece's end lay in the plane of the bin's open end and Manifold left a sliver.
  • lib/gridfinitySolid.ts: the block is square in the corners at an open side (roundedWire takes an optional square, and prism takes a centre and square), the inside's loft and the compartments' cutters are grown as above, and the shelves are cut to an inside that reaches the outline, square in its corners there.
  • The volume checks still throw instead of building a wrong body. The dividers check on an open bin measures what the plain inside would leave by cutting it, as the closed-form volume does not hold once the loft runs past the block; the divider, compartment-cut and compartment-floor bounds leave out the corners and roundings that an open side takes away.
  • ShapeInspector.tsx: the four switches come before the label shelf and scoop switches, from GRIDFINITY_OPEN_WALL_KEYS as the scoops' come from GRIDFINITY_SCOOP_WALL_KEYS; the shelf and scoop rows skip an open side; the compartment card's Label shelf gets the note.
  • The fields are wired through the same places as gridfinityFloorHeight, with the four booleans checked in lylProject.ts. Five keys in fifteen of the sixteen catalogues, a paragraph in guide chapter 09 in the eleven languages with the Gridfinity section, the changelog entry and a whatsNew card.

Testing

On 1.99.0:

  • npm run typecheck
  • npm test (2813 tests, 15 more than 1.99.0's 2798) and npm run test:e2e (438, 15 more than 423)
  • npm run build and npm run export
  • Tried in the editor on 1.98.0: the switches and the shelf and scoop rows they hide, through the panel and the MCP; one undo step per switch; a locked bin; a solid block and a baseplate show no switches; the note on a compartment label already set on an open side; the 15 languages of 1.98.0 on screen for cut-off labels (none; Spanish came with 1.99.0 and was not tried on screen); the Graphite theme at 860 px wide; the exact body with a fillet on an open bin. The pictures below were taken on 1.99.0.
  • Printed: two bins of 1 x 1 x 3 units, open on the sides that face each other, stand in a printed 2 x 1 baseplate as one run (picture below).
  • The unit tests check that a bin with every side closed gives the same triangle counts, volumes and pieces as before this change (the numbers were taken from 1.98.0's code, and the Gridfinity files are the same in 1.99.0), and the same triangles with every switch stored as off; that every one of the 15 ways to open sides gives a closed, one-piece mesh within the outline, with and without the lip, with magnets, on the half-size grid, with a raised floor and one unit high, with scoops and shelves on every wall and with compartments and their labels; the wall and lip taken off one side, as calculated by hand; scoops, shelves and dividers running out to the outline; which bins have sides to open (not a solid block or a baseplate) and that a compartment is offered no label shelf on an open side; the mesh that meshForShape builds for booleans and export; and the fields through a saved .lyl (which refuses a value that is not true or false), the shape settings and the MCP.
  • The e2e tests check that the exact body is one valid solid with the mesh's volume within 0.2 % for open bins with scoops, shelves, compartments and labels; that a closed bin keeps its volume, faces and edges; that two open bins stand 0.5 mm apart; that shelves and dividers reach the open edge; that an open bin whose dividers the kernel lost is refused; and that the lip's sharp top of an open bin takes a fillet and a chamfer.
  • A new jsdom test mounts the settings panel: the four switches, an open side's shelf and scoop switches and settings hidden, no switches on a baseplate or a solid block, and the compartment note.
  • Mutation check: 90 single mutations of this commit, each against the unit and e2e tests. 73 were caught (47 of 50 in the display mesh, 13 of 14 in the exact body); 3 change nothing in the output; 3 drop a key from the private lists in WorkplaneViewport.tsx, which no test reaches, as for the earlier Gridfinity keys there. The 11 gaps (the .lyl check of the four booleans, the mesh that meshForShape builds for export, a compartment label's clip beside an open side, and eight in the settings panel) now have tests, each seen to fail on its mutation.

Notes

  • Changes in your code outside the two Gridfinity files are the field wiring and, in ShapeInspector.tsx, the four switches, the shelf and scoop rows they hide and the compartment note. In gridfinitySolid.ts, roundedWire and prism get optional arguments; a closed bin takes the same path through both as before. The MCP sentence is added to the three SKILL.md copies.
  • Storage, import, export, grouping or undo/redo: four new optional booleans in .lyl (older files open as before); one undo step per switch.
  • Opening a side also removes that direction's scoops against the inner dividers, not only the one at the open side: they are repeated from the bin's scoop on that wall, and that switch is hidden. Keeping them is a small change if you would rather have them.
  • At an open end a short compartment label snaps to full length 0.8 mm earlier than it needs to, as the snap still allows for the lip's lean there. The mesh and the exact body agree; I left it alone.
  • Exact body timings in Node on my machine (median of 5, not measured in the browser): a plain bin of 2 x 1 x 3 units 125 ms closed, 89 ms open at the front, 44 ms open all round; the same bin with 3 x 2 compartments 323 ms closed, 321 ms open at the front. The dividers check on an open bin costs one more kernel cut.
  • Found in the kernel probes: a fillet or chamfer on the floor edge at the open end of a bin with a rounded floor follows the tangent chain and gives a wrong body; a closed bin has no such edge. Without the lip, a 0.5 mm fillet on all top edges gives a wrong body, open or closed, as the wall is 0.95 mm; 0.3 mm, or the outer edges alone, work.
  • If Manifold fails on an open bin, the display mesh falls back to the plain open bin, as it does today for shelves and scoops; the volume and crossing tests check that the pieces are really there.
  • The translations other than English and German are first drafts, Spanish included. Japanese falls back to English, as with the half-size grid, floor, scoop and compartment keys.
  • Left for you to decide: the changelog wording and where the switches sit.

Pictures

[picture: pr682-side-by-side.png] Two bins of 1 x 1 x 3 units, open on the sides that face each other, in the editor.

[picture: pr682-side-by-side-top.png] The same from above: the floor runs through, the walls end square 0.5 mm apart.

[picture: pr682-tray-compartments.png] A tray: 2 x 2 x 3 units, open all round, with 2 x 2 compartments.

[picture: pr682-settings.png] The switches, with Open on the left on and the left shelf and scoop switches gone.

[picture: pr682-print.jpg] The two bins printed, standing in a 2 x 1 baseplate.

🤖 Generated with Claude Code

…there, so bins side by side make one run (henmedia#682)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@henmedia

Copy link
Copy Markdown
Owner

@mlugo-apx thank you, this is a thorough piece of work. I went through it and the checks are green. I will merge it and try it here, so it goes out with the next release. On your two questions: I would keep the scoops against the dividers going with the open side as you have it, and the switches where they are.

@henmedia
henmedia merged commit 0e54b25 into henmedia:main Oct 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants