DEV Community

Elam Uceda Herrero
Elam Uceda Herrero

Posted on

Cutting glass is not cutting wood: writing a guillotine nesting optimiser that uses the offcuts first

Most free "cutting optimisers" on the web were written for sheet goods in a woodworking shop: plywood, MDF, melamine. They pack rectangles onto a board and report how many boards you need. That is a fine problem, but it is not the problem a glass shop has, and the difference changes the algorithm.

I build SyntaxFlow, a set of engineering calculators that run entirely in the browser, and the glass cutting optimiser is the page people use most. Here is what makes glass different, and what that did to the code.

1. Every cut goes edge to edge

A saw can stop in the middle of a board. A glass cutter cannot: you score the sheet and snap it, and the snap runs from one edge to the other. So the layout must be a guillotine layout, and in practice a three-stage one: strips across the sheet, pieces along each strip, and at most one more cut to trim a piece to height.

That rules out the free-form "maximal rectangles" packers that give the prettiest yield on paper. A layout a cutting table cannot execute is worth nothing, however good its percentage looks.

The packer therefore works in strips: it builds the layout as strips across the sheet, pieces along each strip and a final trim, so that every rectangle it returns can be reached by edge-to-edge cuts in a known order. That order is also the one the printed cutting plan lists, so the person at the table cuts in the sequence the screen planned.

2. The edge is not usable, and neither is the line you break on

A float sheet arrives with edges that are damaged or not square, so the first few millimetres all round are trimmed off. Each break also loses a little: the "breakout" width between two pieces. Both are inputs in the optimiser, and both are subtracted before anything is placed. Ignoring them is the most common reason a nest that fits on screen does not fit on the table.

3. The shop already owns glass

This is the part that matters most to a glazier. Against the wall there is a rack of offcuts from earlier jobs: already bought, already paid for, already labelled with their size and their glass.

So the optimiser packs onto the rack before it opens a new sheet. Two rules keep that honest:

  • It only uses an offcut of the same glass. A 6 mm clear offcut is never offered for a 4 mm low-e order, so the description is matched, not just the size.
  • It refuses to open an offcut unless doing so removes a whole new sheet from the order. Cutting into labelled stock to save nothing makes the shop poorer: the rack loses a known, reusable piece and the order still buys the same number of sheets.

On the worked example published on the page (forty panes on 3210 x 2250 mm stock) two racked offcuts take the job from four new sheets to two.

4. The waste is money, so say it in money

The result shows sheets to buy, yield, and waste in square metres. But a shop thinks in money, so if you type your price per square metre it also shows what the scrap of that job costs. Offcuts at least 150 mm on both sides count as offcuts, not scrap: they go back on the rack, and the next job can use them.

5. Nothing leaves the browser

The whole thing is plain JavaScript in the page. The cutting list, the rack and the saved jobs live in the browser's own storage. There is no account to make and nothing is uploaded, which also means the page keeps working on a phone at the cutting table with a weak signal.

Try it

The optimiser is free to use, with no sign-up: https://syntaxflow.io/glass/cutting-optimiser/

There is a version in Spanish, German, French, Portuguese and Italian, linked from the page. The printed cutting plan, labels for every pane and the offcut rack are on the same site.

If you write nesting code yourself, I would like to hear how you handle the "only open an offcut if it saves a sheet" rule: it is simple to state and surprisingly easy to get wrong.

Top comments (0)