lamina3d 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. lamina3d-0.2.2/.gitignore +17 -0
  2. lamina3d-0.2.2/CHANGELOG.md +309 -0
  3. lamina3d-0.2.2/LICENSE +661 -0
  4. lamina3d-0.2.2/PKG-INFO +535 -0
  5. lamina3d-0.2.2/README.md +506 -0
  6. lamina3d-0.2.2/core/__init__.py +0 -0
  7. lamina3d-0.2.2/core/checks.py +381 -0
  8. lamina3d-0.2.2/core/export.py +432 -0
  9. lamina3d-0.2.2/core/geometry.py +239 -0
  10. lamina3d-0.2.2/core/model.py +85 -0
  11. lamina3d-0.2.2/core/modes/__init__.py +239 -0
  12. lamina3d-0.2.2/core/modes/curve.py +266 -0
  13. lamina3d-0.2.2/core/modes/folded.py +448 -0
  14. lamina3d-0.2.2/core/modes/interlocked.py +159 -0
  15. lamina3d-0.2.2/core/modes/radial.py +339 -0
  16. lamina3d-0.2.2/core/modes/stacked.py +439 -0
  17. lamina3d-0.2.2/core/nest.py +359 -0
  18. lamina3d-0.2.2/core/notch.py +115 -0
  19. lamina3d-0.2.2/core/plan.py +570 -0
  20. lamina3d-0.2.2/core/solid.py +343 -0
  21. lamina3d-0.2.2/core/split.py +140 -0
  22. lamina3d-0.2.2/core/testmodels.py +106 -0
  23. lamina3d-0.2.2/core/unfold.py +190 -0
  24. lamina3d-0.2.2/examples/README.md +18 -0
  25. lamina3d-0.2.2/examples/blob.stl +0 -0
  26. lamina3d-0.2.2/examples/bowl.stl +0 -0
  27. lamina3d-0.2.2/examples/bracket.stl +0 -0
  28. lamina3d-0.2.2/examples/bunny.stl +0 -0
  29. lamina3d-0.2.2/examples/cone.stl +0 -0
  30. lamina3d-0.2.2/examples/cow.stl +0 -0
  31. lamina3d-0.2.2/examples/cow_spot.stl +0 -0
  32. lamina3d-0.2.2/examples/cube.stl +0 -0
  33. lamina3d-0.2.2/examples/cylinder.stl +0 -0
  34. lamina3d-0.2.2/examples/dumbbell.stl +0 -0
  35. lamina3d-0.2.2/examples/egg.stl +0 -0
  36. lamina3d-0.2.2/examples/head_igea.stl +0 -0
  37. lamina3d-0.2.2/examples/horse.stl +0 -0
  38. lamina3d-0.2.2/examples/horse_statue.stl +0 -0
  39. lamina3d-0.2.2/examples/interlocked.png +0 -0
  40. lamina3d-0.2.2/examples/pear.stl +0 -0
  41. lamina3d-0.2.2/examples/presets.json +29 -0
  42. lamina3d-0.2.2/examples/pyramid.stl +0 -0
  43. lamina3d-0.2.2/examples/sheet_interlocked.svg +307 -0
  44. lamina3d-0.2.2/examples/snowman.stl +0 -0
  45. lamina3d-0.2.2/examples/sphere.stl +0 -0
  46. lamina3d-0.2.2/examples/stacked.png +0 -0
  47. lamina3d-0.2.2/examples/tall_bar.stl +0 -0
  48. lamina3d-0.2.2/examples/torus.stl +0 -0
  49. lamina3d-0.2.2/examples/tube.stl +0 -0
  50. lamina3d-0.2.2/examples/twisted.stl +0 -0
  51. lamina3d-0.2.2/examples/wavy_torus.stl +0 -0
  52. lamina3d-0.2.2/examples/wedge.stl +0 -0
  53. lamina3d-0.2.2/pyproject.toml +76 -0
  54. lamina3d-0.2.2/web/app.py +428 -0
  55. lamina3d-0.2.2/web/browser.py +49 -0
  56. lamina3d-0.2.2/web/static/browser-worker.js +60 -0
  57. lamina3d-0.2.2/web/static/browser.js +50 -0
  58. lamina3d-0.2.2/web/static/feedback.js +171 -0
  59. lamina3d-0.2.2/web/static/index.html +1489 -0
  60. lamina3d-0.2.2/web/static/logo.svg +14 -0
  61. lamina3d-0.2.2/web/static/vendor/OrbitControls.js +1417 -0
  62. lamina3d-0.2.2/web/static/vendor/STLLoader.js +410 -0
  63. lamina3d-0.2.2/web/static/vendor/three.module.js +53044 -0
@@ -0,0 +1,17 @@
1
+ working-files/
2
+ out/
3
+ _site/
4
+ dist/
5
+ .venv/
6
+ __pycache__/
7
+ *.pyc
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+ .mypy_cache/
12
+
13
+ # scratch that must never reach a public repo
14
+ Claude outputs/
15
+ _to_delete/
16
+ .playwright-mcp/
17
+ graphify-out/
@@ -0,0 +1,309 @@
1
+ # Changelog
2
+
3
+ What changed in each release. The GitHub release for a version is this section, pasted.
4
+
5
+ ## 0.2.2
6
+
7
+ What your model weighs, eleven more materials, PLA and PETG printed plate by plate at full size, a check that the
8
+ material can fold before a folded job is cut, curve ribs that branch down legs and arms, dowels that hold big layers
9
+ near their edge, the design's name on every part and every file, a button that squares up a tilted model, a desktop
10
+ version that keeps itself up to date, and an auto-fix that never deletes part of your model. And many fixes: stacks
11
+ that came out short, parts placed off their sheet, pieces of one layer nested as one, and the browser version's
12
+ occasional failure.
13
+
14
+ ### Printing
15
+
16
+ - **A printed job is plates, not sheets.** Picking PLA or PETG ticks **3D printed** on the Sheet & fit tab: the sheet
17
+ is the printer's bed, the page counts plates, and the Export tab offers one 3MF per plate, at full size and with the
18
+ clearance set for printing, instead of cut files. Untick it to get the cut files anyway.
19
+
20
+ ### Checks
21
+
22
+ - **Folded panels check that the material can fold.** Fold lines, and tabs that fold over a seam, in 3 mm plywood
23
+ (or MDF, acrylic, balsa, foam board, printed PLA or PETG, or card and metal past the thickness they fold at) are an
24
+ error now: the sheet would crack along the fold. One click cuts every face as its own panel, joined by ribs that
25
+ need no fold, with triangles big enough to keep the number of parts reasonable. A material of your own is checked
26
+ as the one it was based on.
27
+
28
+ ### Weight
29
+
30
+ - **The Export tab weighs the job**: the parts as cut (holes and slots taken out), the whole sheets you buy and lift
31
+ onto the machine, and the dowels, with a total for the assembled model. A job that mixes thicknesses gets a line
32
+ per stock. It follows the units switch: grams and kilograms, or ounces and pounds. It matters most for big pieces
33
+ and metal, and for anything that has to hang.
34
+ - **Every material has a density** you can correct on the Sheet & fit tab. The figures are typical ones; weigh an
35
+ offcut of your own stock for an exact number.
36
+ - **Materials of your own**: + beside the material keeps the one in use under a name, with its thickness and
37
+ density, and − deletes it.
38
+
39
+ ### Model
40
+
41
+ - **Square it up.** A boxy model sitting a few degrees off square (a rotate slider left at 85 instead of 90, a CAD
42
+ export that came out tilted) cuts every straight edge as a staircase. The Model tab now says how far off it is,
43
+ "sits 5° off square", with a **square it up** button under the rotate controls. Nothing turns by itself: leave it
44
+ if the tilt is on purpose.
45
+ - **Radial models with lobes side by side or at right angles.** Three balls on a neck, each with its own axis, no
46
+ longer have their spine cut into loose pieces. Two axes at right angles work when they lie in one plane: the
47
+ dumbbell now opens that way, across the lower ball and up the upper one.
48
+
49
+ ### Curve
50
+
51
+ - **Curve (ribs) takes branches**: one line per leg, arm or tail, each with its own ribs square to it and a spine
52
+ that reaches into the body and slots into its ribs. A horse's legs are held instead of cut across by the body's
53
+ ribs: with a branch down each leg it comes out in 55 parts and no errors. Shift+alt-click a hoof to add a branch,
54
+ drag its ends to move it, alt-click it to remove it. A branch that starts past the body's ribs is an error that
55
+ says where to move it, instead of a loose leg.
56
+ - **The body's ribs can follow a tighter curve**, now that the legs no longer get in the way.
57
+ - **The curve's points are a table you can edit.** Typing in the old box broke the slice.
58
+
59
+ ### Examples
60
+
61
+ - **The horse opens in Curve**, with its curve from tail to muzzle and a branch down each leg: 55 parts, no errors.
62
+ - **A new horse for stacked slices**: `horse_statue`, a porcelain horse rearing on a round base (CC0, from Poly
63
+ Haven). It opens as side profiles with a 4 mm gap on 2 mm square dowels: 39 parts, no errors, no warnings.
64
+ - **The wavy torus**: a ring rising and falling in three waves, with a channel along it for an LED tube, stacked in
65
+ PETG for a 3D printer.
66
+ - **The page now opens on the blob.**
67
+
68
+ ### Stacked dowels
69
+
70
+ - **Dowels hold a big layer near its edge.** On a round model the widest layers used to hang on two dowels close
71
+ together in the middle, free to wobble at the rim. Such a layer now gets dowels of its own out toward its edge,
72
+ and three or more go round the layer instead of along a line. Where a layer is still held by dowels too close
73
+ together, the Checks tab says so and offers a button that adds the dowel that would hold it. Where the wall is too
74
+ thin for a dowel farther out (a hollowed model), it says how thick the wall is and what the dowel needs.
75
+ - **A dowel you add comes on top of the automatic ones.** One you alt-clicked or typed in used to count as one of
76
+ the dowels per layer you had asked for, so the layer could end up held no better. Now it is added to them.
77
+
78
+ ### Materials
79
+
80
+ - **Nine new ones to cut**: stainless steel, brass, copper, greyboard, polypropylene, foam board, EVA foam, basswood
81
+ and balsa, each with the thicknesses it is sold in, its sheet sizes, a 3D look, and only the machines that can cut
82
+ it.
83
+ - **Stainless has its own gauge table.** 14 gauge stainless is 1.984 mm where carbon steel's is 1.897 mm, so
84
+ picking "steel" for it cut every slot too tight. Copper is listed by ounces per square foot and chipboard by
85
+ points, the way they are sold.
86
+ - **Foam board is cut by hand only**: its polystyrene core melts and can catch fire under a laser.
87
+ - **PLA and PETG, to 3D-print the parts at full size.** Their thicknesses are whole print layers (0.8 to 6 mm),
88
+ their "sheets" are print beds, and a 3D printer gives every slot 0.2 mm of clearance. Six printers are listed with
89
+ their beds: Bambu Lab H2C, X1 / P1 / A1 and A1 mini, Prusa MK4S and CORE One, Creality Ender-3 V3.
90
+
91
+ ### Labels and cut files
92
+
93
+ - **Every part carries the design's name**: `bunny Z-3`, so parts of two models cut together are never mixed up,
94
+ even though both have a Z-3. It is the project's name when you have given one, otherwise the model's file name.
95
+ **label model** on the Sheet & fit tab turns it off.
96
+ - **Every file is named after its design too.** Each file in a download starts with the same name as the zip: the
97
+ project's or the model's, with its revision, as in `egg_v1.0 sheet1 plywood.svg`, `egg_v1.0 Z-1 plywood x4.svg`
98
+ and `egg_v1.0 cut-list.txt`. Two designs unzipped into one folder no longer overwrite or mix with each other.
99
+ - **The cut list gives each part's size**, width × height as it lies in its file, in your units.
100
+ - **A material of several words is one word** in a file name: `egg_v1.0 Z-1 stainless-steel x4.svg`. The spaces
101
+ always separate design, part, material, thickness and quantity.
102
+
103
+ ### 3D view
104
+
105
+ - **The controls under the view are one short line**: orbit, zoom and pan. **all controls** opens the rest, grouped
106
+ by what they work on. The handles of a selected part are explained in the panel that opens with it.
107
+
108
+ ### On your computer
109
+
110
+ - **Updates come by themselves.** The double-click starter installs the newest release each time it starts, and
111
+ starts the one you have when there is no internet. A starter downloaded before this version never updates:
112
+ download the ZIP once more and use the new one; your jobs stay in the old folder's `working-files`.
113
+ - **From a terminal it is one install:** `uv tool install lamina3d`, then `lamina3d` opens it, and
114
+ `uv tool upgrade lamina3d` updates it.
115
+
116
+ ### Docker
117
+
118
+ - **The image runs on Debian 13**, as the Debian 12 base it was built on is no longer updated. Nothing changes in how
119
+ you run it.
120
+ - **Dependencies are kept up to date**: the Python packages, the Docker base image and the build tools are checked
121
+ every week, a new release is only taken once it is a week old, and every image is built and tested before an
122
+ update is merged.
123
+
124
+ ### Gallery
125
+
126
+ - **Show what you made.** The landing page has a gallery of things cut with Lamina, and a **send me a photo** link
127
+ under the downloads on the Export tab opens a prefilled email (no account needed) or a GitHub issue form you drag
128
+ the photos into. With your OK it goes up, credited the way you ask. Or post it on Instagram or X with
129
+ **#applamina**.
130
+
131
+ ### Auto-fix
132
+
133
+ - **Auto-fix never deletes a piece of your model.** It used to add crossing slices and then remove whatever still
134
+ floated: on a tube that was most of the model, and on the horse the whole top layer with its ears. Now a piece
135
+ nothing can hold stays, with its error and the fixes to click, deleting among them if that is what you want. The
136
+ only things left out, and the report says so, are slivers too thin to cut: shavings a slot cuts off its own part,
137
+ and specks where a slice only grazes the surface.
138
+ - **Interlocked slices are added where they actually hold.** A crossing slice through the middle of a loose piece
139
+ was often just as loose there. Auto-fix now places it where it connects the piece to the rest of the model: the
140
+ tube and the torus are held whole.
141
+ - **The remove choice of auto-fix is gone**: **add** holds what it can, **off** only reports. A project saved with
142
+ remove opens with off.
143
+
144
+ ### Usage counting
145
+
146
+ - **The box at the foot of the published app's Model tab now starts ticked.** While it is ticked it sends the
147
+ technique you pick, whether the model came from the examples or your computer, and which formats you export:
148
+ never the model, a file name, your measurements, an account or a cookie. Untick it and it stays off in that
149
+ browser. The copy you run yourself or in Docker counts nothing at all.
150
+
151
+ ### Fixed
152
+
153
+ - **The browser version no longer fails now and then while nesting.** The bunny example hit it about one time in
154
+ three; it came from the geometry library the browser version runs.
155
+ - **Stacked slices run the full height of the model.** A 100 mm cube in 4 mm card came out 23 layers tall, with the
156
+ missing 8 mm all at the top. It is 25 layers now, centred.
157
+ - **A stack never loses layers to the automatic fixes.** With a space between layers and dowels along lines, a
158
+ layer no line crossed yet was removed: 11 of the horse's 20. It stays now, and the Checks tab says what would
159
+ hold it.
160
+ - **Only the handles move a selected part.** Dragging anywhere on a selected layer used to slide it, which is also
161
+ how you turn the view, so layers moved by accident. A plain drag now always turns the view; the arrow and rings
162
+ (or shift- and ctrl-drag) still move, tilt and roll it.
163
+ - **Random dowels spread across each layer** instead of sometimes bunching at one end.
164
+ - **Dowel lines work from the first click.** The **+ line** button added an empty line that placed nothing; it now
165
+ draws one up through the stack, and alt-click draws one through the point you click.
166
+ - **Folded panels keep a proper wall around their holes.** Rivet, laced and strip joints put their holes too close
167
+ to the edge, and the one-click fix changed a setting folded panels do not use. The holes keep the full wall now,
168
+ and the fix, when it is needed, changes the hole size.
169
+ - **Your own model starts from its own shape.** Uploading after an example kept that example's size, rounding and
170
+ thickening, so Julia's square 100 mm cube came out 308 mm across with rounded corners and its small hole closed.
171
+ An upload now starts with every Model setting at zero, the note after a remesh says how much it rounds the
172
+ corners, and a model under 5 mm across (an STL saved in metres) gets a note asking for its real size.
173
+ - **Stacked slices no longer get stuck at "placing slices and slots"** on a model with flat walls, like a box with a
174
+ hole: it never finished, and now takes about 18 s. Thanks to Colin for the report and the project file.
175
+ - **A tall slanted part is measured at its real size.** It could read as 0 mm wide, and was reported "too thin"
176
+ instead of being split to fit the sheet.
177
+ - **Report a problem works while the page is stuck.** In the browser version, the report waited for a slice that
178
+ would never finish, so it could only be sent after reloading, which lost what it was about.
179
+ - **Picking the same file again loads it.** After switching to an example, choosing the file you had uploaded
180
+ before did nothing.
181
+ - **The local and Docker versions no longer finish slices nobody is waiting for.** Dragging a slider through a few
182
+ values computed every one of them to the end, side by side, and made each slice several times slower.
183
+ - **A problem report says how you got there.** Besides the settings and the checks, it now carries the Lamina
184
+ version and every step since you loaded the model (each setting changed, undo, fix clicked, slice and error), and,
185
+ if a slice is still running, how long it has taken. **See what is sent** in the report dialog shows all of it
186
+ before you send. Saving a project is unchanged: it holds the design, not the steps.
187
+ - **A dowel in the 3D view has the shape of its hole.** Square, hexagonal, cross and slot dowels were all drawn
188
+ round, so changing the shape seemed to change nothing. Their weight uses the real shape too.
189
+ - **Every piece of a layer is its own part.** A layer that falls apart into separate shapes, like the lobes at the
190
+ ends of the wavy torus, was one part: its pieces were nested together with the empty space between them, and only
191
+ one had a label. Each piece is now a part of its own, labelled `Z-1-1`, `Z-1-2` …: the wavy torus goes from 14
192
+ sheets to 8.
193
+ - **Aligned tab spacers hold every layer.** Every second pair of layers could end up with no spacer at all, and
194
+ spacers that did fit could cut into each other. Each spacer is now placed where its slot really fits both layers,
195
+ with a full wall around it.
196
+ - **A new example starts every technique fresh.** Switching the horse to stacked after the statue brought back the
197
+ statue's 2 mm square dowels on its side axis, so every tab spacer came out too thin to cut. An example now opens
198
+ every technique on its defaults and its own preset; your own model keeps the settings you gave it.
199
+ - **A spacer too thin to cut says why, and how to fix it.** Tab spacers and pegs are as wide as the connector, but
200
+ their error told you to thicken or round the model, which never reaches them. It now names the connector size, and
201
+ one click sets one that works.
202
+ - **Turning the view while a model loads turns the view.** On the Model tab, a drag across the view while a new model
203
+ was slicing could catch a turn ring and stand the model on its head. While a slice runs, a drag only turns the view.
204
+ - **Every part lands on its sheet.** A part that filled a sheet almost exactly, like a big folded panel, could be
205
+ placed far off the sheet, big jobs could run a part into the sheet margin, and now and then two parts were nested on
206
+ top of each other. Every part is placed inside the margin and clear of the others now.
207
+ - **Interlocked slices added by auto-fix keep a full wall from each other.** One could land so close to another that
208
+ barely 1 mm of material was left between their slots.
209
+
210
+ ## 0.2.1
211
+
212
+ Units and file names, both reported after 0.2.0.
213
+
214
+ ### Units
215
+
216
+ - **The units switch now changes every length on the page.** Before, some places stayed in mm: the panel of the part
217
+ you had selected, the parts table, the Export tab's boxes, the messages and fix buttons, and the help. Now they all
218
+ follow the switch, straight away, without slicing again.
219
+ - **Nothing is rounded when you change units.** Lengths are kept exactly as you typed them, and the units only
220
+ change how they are shown. 1/16 in is 1.5875 mm, where editing a single part used to store 1.59 mm. Switching back
221
+ and forth any number of times leaves every value where it was.
222
+ - **The boxes step in round numbers of your unit.** In inches the thickness box used to step by 0.0019685 and mark
223
+ 0.25 as invalid. It now steps by 0.002. An exact inch fraction reads as one, as in `1/16 in stock`.
224
+ - **Cut files come out in the units on screen**, even if you changed them after the last slice.
225
+
226
+ ### File names
227
+
228
+ - **Per-piece files say what they are**: part, material, thickness, then quantity, separated by spaces. For example,
229
+ `R-1a cardboard x2.svg`. Every file ends in its quantity, `x1` included. Sheet files carry the material too:
230
+ `sheet1 cardboard.svg`.
231
+
232
+ Verified by 579 tests, plus 16 driving the app in a real browser (one of them for units) and one slicing the
233
+ published build end to end.
234
+
235
+ Known issue, also in 0.2.0: in the browser version, the bunny example now and then fails to slice with a geometry
236
+ error (`GEOSException … NaN/Inf`). It shows up in about one run in three of the end-to-end test and is being looked at.
237
+
238
+ ## 0.2.0
239
+
240
+ Most of this came from people who wrote in after trying 0.1.0. Thank you — keep them coming.
241
+
242
+ ### Install and run
243
+
244
+ - **Double-click to start**, on Windows, macOS and Linux. No terminal, no commands.
245
+ - **No upload limit on your own machine.** The 30 MB cap was a public-server measure applied to everybody.
246
+ - **A model that fails to load says so in a dialog**, and lets go of the file box.
247
+
248
+ ### Model preparation
249
+
250
+ - **`round`, `shrinkwrap`, `hollow` and `thicken` keep a smooth model smooth.** All four go through one voxel grid,
251
+ which left a staircase and then a bumpy edge. Both are gone: on the egg at `round 2`, edges over 45° went
252
+ **13 % → 0 %** and the cut outline's wobble **0.285 mm → 0.092 mm**. You no longer need `smooth` to undo the tool.
253
+ - **A model that is not watertight is mended first** — merged, de-duplicated, holes filled — instead of going
254
+ through the remesh that put steps on every slice.
255
+
256
+ ### Stacking
257
+
258
+ - **Layers get alignment dowels by default**, two per piece, so a stack glued with no gap cannot go together
259
+ crooked. Each piece of a layer that falls into two gets its own pair.
260
+ - **Dowel holes keep a wall of material between them.** They used to merge into one ragged opening — 6 mm holes
261
+ 0.6 mm apart on a hollowed model, 3.4 mm on a cone.
262
+ - **A dowel runs straight through as many layers as it fits.** Holes used to creep inward on anything tapered until
263
+ they collided and were dropped; the scanned head went from 20 dowels to 38.
264
+ - **Where none fits, it says so** and any size it suggests is one that works.
265
+
266
+ ### Cutting
267
+
268
+ - **Parts bigger than your sheet** are cut the long way and then across; whatever still cannot fit keeps a sheet to
269
+ itself instead of being nested on top of. The report names the size that would fit.
270
+ - **`one sheet` with many parts is 550× faster** — 2552 s → 4.6 s on 400 panels.
271
+
272
+ ### On screen
273
+
274
+ - **Your model appears seconds in**, while the slices are still being cut, and the overlay lists the stages
275
+ (`step 5 of 9 · sectioning · 12 of 34 · 46 %`) instead of a bar that restarts.
276
+ - **The sheet preview is readable without colour vision** — the Okabe–Ito set, drawn thicker. Exported files keep
277
+ the machine colours.
278
+ - **A selected part has handles on the part**: an arrow along its normal, two rings to turn it about its own middle.
279
+ Radial half-slices and the planes between lobes used to swing across the model when dragged.
280
+ - **Curve points follow your pointer from any view**, instead of plunging along an axis you cannot see.
281
+ - **Nothing follows you from one model to the next**: axes, curve points, dowels and per-slice edits are cleared.
282
+ - **What changed shows itself once** after an update, and the **what's new** button in the header has every version,
283
+ newest first — these notes, so they cannot drift from the release.
284
+
285
+ ### Checks, machines, finding your way
286
+
287
+ - **A layer of a stack is never offered for deletion** — take it out and the model has a gap through it. A floating
288
+ island *of* a layer still is.
289
+ - **16 machines by name** (Glowforge, xTool, OMTech, K40, Epilog, Thunder, Trotec, Shapeoko, Cricut, Cameo and more),
290
+ each marked `*`: published bed sizes and an educated guess at kerf, not measured on your material. Plus metric
291
+ thicknesses, and a button to share a machine or material so it ships with Lamina.
292
+ - **`? help`** in the header: the tabs in the order you use them, the 3D mouse, every shortcut.
293
+ - **Undo is labelled**, and holding Ctrl+Z slices once at the end instead of once per step.
294
+ - **The size boxes** show the model's real dimensions: type one and the other two follow.
295
+
296
+ ### Also
297
+
298
+ Radial slicing with several axes (a snowman, a dumbbell) tied by a spine · `assembly-key.txt` in the export ·
299
+ puzzle mode · the assembly as a video · folded panels from an open surface · fit tests at print and cut scale ·
300
+ a report button that writes the bug report for you.
301
+
302
+ Verified by 579 tests, plus 15 driving the app in a real browser and one slicing the published build end to end.
303
+ Not tested here: the macOS and Linux starters (Windows only), and the starred machine figures.
304
+
305
+ ## 0.1.0
306
+
307
+ First public release: five construction techniques (stacked, interlocked, radial, curve, folded), the physical
308
+ checks with one-click fixes, nesting, SVG / DXF / PDF / EPS export, the 3D-printable prototype set, and the browser
309
+ build that needs no install.