Commit Graph
100 Commits
Author SHA1 Message Date
matthewtrahan 88e7184976 tests: rows -- build on the L-bracket and tube at X40 and leave less bare, never more bare than the patch fill where they lose (wedge, ramp, torus, bar), outside the part and clear of every support, deterministic; the length field's calls 2026-10-16 08:41:38 -05:00
matthewtrahan c6aec8661b ui: Long walls checkbox under Plate only, shown in Full coverage only, on by default -- untick for the patch fill alone; undoable and saved with the session; de/pt/ar strings; site-only in the plugin options test 2026-10-16 08:41:38 -05:00
matthewtrahan ea158a4b84 fill: Long walls on by default in Full coverage (opts.longWalls) -- the rows run, then the patch lines exactly as before (the step-1 heading order on the patch lines is gone: little gain, and its extra lines ran a Plate only portal into the check cap); built with and without rows, the rows kept only if they leave no more red bare (a wedge at X40: 17 -> 47 mm2 with them); fill reports its rows 2026-10-16 08:41:38 -05:00
matthewtrahan 6f9f19fba2 fill rows: search budget back to 900 builds -- the grid made the greedy pick cheap; Isaac upright 81 -> 86% must-hold 2026-10-16 08:41:38 -05:00
matthewtrahan 8a0c157ee7 fill: rows (opts.alignFill, off) -- long walls along the model's length before the patch lines (fins/rows.js: each row's longest buildable pieces by Draw's builder, greedy by red held); keep() pulled out of wallFor; no clear length = x 2026-10-16 08:41:38 -05:00
matthewtrahan b142a96d28 prototype: fill rows -- parallel rows along one heading, each row's longest buildable pieces by Draw's builder; Isaac must-hold 76 -> 89% (11 walls, 2.6 -> 4.3 g), mixed on other figures 2026-10-16 08:41:38 -05:00
matthewtrahan f2393c0327 fill: opts.alignFill (experiment, off) -- each group's lines try the model's length first (fins/field.js: the plan long axis of the surface within 20 mm), then 15deg either side, then the best of the rest; on Isaac 14 -> 17 walls, must-hold 76 -> 77%, still 3-5 mm stubs 2026-10-16 08:41:38 -05:00
matthewtrahan dd0c597b37 ui: search review fixes -- results follow an undo, a build or anything else that shows or hides a row (it watched only change events); the brace tine fields point at Tines when that's what hides them; Restore all points at Remove fins, Remove selected at nothing; the hidden mode menu's options no longer count as Placement's name; the no-match line is announced 2026-10-16 07:43:18 -05:00
matthewtrahan 1c9fe96c13 ui: search the settings -- a box at the top of the panel narrows it to the settings whose name matches, opening the sections they're folded in; a match the current mode hides brings the switch that reveals it
Local issue 42. Names first (shown and English), tooltips only when no name matches;
Esc or the x puts the panel back as it was, and a search never saves a section's
open state. Layout only: no value changes (ui/search.js).
2026-10-16 07:43:18 -05:00
matthewtrahan 8d353753bf fill: note the box grid key's range (review) 2026-10-16 07:39:48 -05:00
matthewtrahan ad57031711 fill: the support box grid buckets by height too -- a tall wall's boxes and Auto's tines stacked in one plan cell, so every clearance check walked them all; same walls, Full builds 2-6x faster on the real figures (Isaac X30 12.2 -> 2.0 s, bunny X-30 11.1 -> 1.6 s, buster X-30 40.9 -> 17.2 s) 2026-10-16 07:39:48 -05:00
matthewtrahan 6c6f9694b3 ui: a saved session restores its layer height and gap again (review) -- the fins it lists as removed are matched by heights the gap shifts, so opening it at another gap brought them back; the browser still starts a new part from your last values 2026-10-15 22:09:44 -05:00
matthewtrahan 4664bd627a ui: More settings review fixes -- the changed count stays on the line while the section is open, the sway switch drops its 'tall parts' hint under the Tall parts heading, and the wall-lines exception is described as the guard it is 2026-10-15 22:09:44 -05:00
matthewtrahan 2d82ff6866 ui: More settings -- bed pad, wall lines, sway braces, wide-face coverage, plate only and the display toggle fold into one section grouped by intent (Hold the part / Tall parts / Where supports go / Display), with an "N changed" count and a dot on each changed field
Local issue 42, step 3. In view by default: the printer row, Placement, Tines and
Cutouts. Every control keeps its id; the Clearances, Sway, Walls and Display
headers and their recaps go. A field counts as changed only while the build reads
it (a hidden or disabled field doesn't), and Wall lines not when a big nozzle took
its default away (ui/more.js).
2026-10-15 22:09:44 -05:00
matthewtrahan bd6470b17b ui: the layer height and support gap are remembered across visits like the nozzle -- they're the printer's, so a saved session neither saves nor applies them; interface material stays with the part 2026-10-15 22:09:44 -05:00
matthewtrahan 3ee3de1fb2 ui: the layer height stays shown while Interface material is on -- the band is one layer of the wall top, but with tines off and a Sure hold pad the field hid and the printer line dropped it (review) 2026-10-15 21:36:44 -05:00
matthewtrahan ec529e0a5b ui: a printer row at the top of the settings -- nozzle, layer height, support gap and interface material on one line (0.4 nozzle · 0.2 layers · 0.2 gap) that unfolds in place; Placement stands under it without a header
Local issue 42, step 2. The four fields move unchanged (every id kept); the Tines
and Clearances recaps stop repeating the layer height and gap. The line names only
what the build reads: layers drops out while the layer height is hidden.
2026-10-15 21:36:44 -05:00
matthewtrahan 497f857c3d export: waits while a rebuild is out (review) -- a nozzle or layer change exported mid-build named the old fins with the new settings, the mismatch #279 is about 2026-10-15 21:04:59 -05:00
matthewtrahan 66a5e4c62a export: the file name carries the nozzle and layer height the fins were built for (#279) -- part-fins-0.6nozzle-0.24layer.3mf, so the slicer gets set to match: a 0.4 build sliced at 0.6 prints its walls as one line and drops tines between 0.24 layers 2026-10-15 21:04:59 -05:00
matthewtrahan bff031d484 placement: review fixes -- the button group takes its screen-reader name from the translated Placement label, and a focused button's ring draws over its neighbour 2026-10-15 20:49:39 -05:00
matthewtrahan 1ccec211cf placement: Auto / Full coverage / Draw as three joined buttons with a one-line note on what the chosen mode does, in place of the dropdown (local issue 42) -- the select stays, hidden, as the one place the mode is kept (undo, saved sessions and ui-smoke read and set it); the buttons drive it and follow it through undo/redo 2026-10-15 20:49:39 -05:00
matthewtrahan e562b67680 rotate: review fixes -- the drag label hides while any toolbar popover is open (it ran under Suggest, and over Rotate opened mid-fade), drops aria-live (a drag queued an announcement per frame), and follows the badge row's sideways scroll on a phone 2026-10-15 18:42:46 -05:00
matthewtrahan f9351d8239 rotate: a ring drag with the Rotate popover folded shows its angle in a small label above the Rotate badge (the turn so far, then the pose), fading 1.2 s after release -- the readout moved into the popover in #286, so a drag showed no angle; ui-smoke's ring drag now drives the rotate gizmo (it found the Section plane's) 2026-10-15 18:42:46 -05:00
matthewtrahan 684ab98cfb toolbar: review fixes -- folding the Rotate popover disarms Lay a face flat (its button was the only sign it was armed, and a stray click re-laid the part), a popover scrolls inside a short window and stays inside the window's left edge, Esc hands focus back to the badge, Undo/Redo take their name from the translated title, the Suggest chevron's CSS goes 2026-10-15 15:51:17 -05:00
matthewtrahan 06a1322466 toolbar: the left pane's pose and view tools move into the bottom view toolbar -- Undo/Redo, then Rotate (90° steps, Reset, Lay a face flat, rotate rings), Suggest, Strength (lit while a load is set), Section and View (Mouse preset, Show layers); each popover opens above its own badge and extends right; the left pane keeps only the stats card (local issue 42) 2026-10-15 15:51:17 -05:00
matthewtrahan 292e8a16b6 plugins menu: review fixes -- the command line's slicer list moves to its plain line (the orange note is for warnings), the LayerLing route is said to be untried, Deno gets its command, Sie in German, Brazilian Portuguese, and Arabic agreement 2026-10-15 15:29:21 -05:00
matthewtrahan 20c2a9e95d plugins menu: the MCP server, and who the command line is for -- slicers with no plugin system (Bambu Studio, QIDI Studio, Creality Print, Snapmaker Orca, Flashforge) use it in place of a plugin; design tools with an MCP server but no plugins (LayerLing) reach the fins through the MCP server 2026-10-15 15:29:21 -05:00
matthewtrahan 0bea7ad741 pad: review fixes -- a coarse block whose fan folds over (near the oval's tips: reversed facets lying on the top, which closed/oriented checks pass) is meshed fine, its hub is its corners' mean; a Custom pad thinner than half a layer marks the triangles its ramp follows
Reviewer fuzz (210 random boxes, Light/Custom, layers 0.08-0.4, gaps, grips, margins): every slice now equals the full 0.1 mm grid's at 13 heights, no folds, no open edges; 30 cases folded before. Main's band scan was itself coarse in a few places (tips, thin Custom pads), so a few golden slices move to the full grid's.
2026-10-15 14:30:23 -05:00
matthewtrahan bb649270a7 pad: the Light/Custom pad is 0.1 mm only in the 1.2 mm blocks the part comes near -- every column shared one set of rows, so one dip near the rim made a 128 mm figure's pad 2M cells in Suggest (RangeError at 4x); now 19k, and every slice is the same segments as before
Fine blocks keep the full grid's nodes and diagonals, and the rim keeps every node, so the pad's sections at ten heights match main segment for segment (cube X20-45, Light/Custom, 0.12-0.28 layers; man bust, buster, Isaac). A coarse block beside a fine one fans from its centre through the shared nodes, so there are no T-junctions. A coarser grid was the other option and was dropped: at a 0.3 mm cell the gap closes to 0.080 mm at a cube's corners. Goldens re-recorded: only the pad's triangles changed.
2026-10-15 14:30:23 -05:00
matthewtrahan ab0b25dbe8 mcp: review fixes -- the tools say they may replace a file (output can name one), object must be a number or name, an own-property check on tool keys, ids must be strings or integers, no 2025-03-26 (batches), errors in setting names throughout, and the release note's add command takes a full path 2026-10-15 14:27:57 -05:00
matthewtrahan 25a317722e mcp: build it in CI, drive it over stdio on Node outside the checkout, and publish support-fins-mcp.mjs with the other plugins 2026-10-15 14:27:57 -05:00
matthewtrahan 9919c32bb8 mcp: Support Fins as an MCP server -- fin_part and fins_only for AI clients (Claude Code, Claude Desktop), each a CLI run underneath, so a tool call writes the CLI's exact bytes; settings schema from the CLI's flags in the site's units; stdio on Deno or Node 2026-10-15 14:27:57 -05:00
matthewtrahan e0122ae429 cli: export the flag table and let the bundler take another entry -- the MCP server builds its settings schema from the same flags and ships as the same one-file bundle 2026-10-15 14:27:57 -05:00
matthewtrahan 4b46f94fec ui-smoke: the PETG step sets Support gap 0.3 -- the Material dropdown it set is gone (b625eed), so every run failed at that step; README counts 87 steps 2026-10-15 11:42:42 -05:00
matthewtrahan b59de82e3a cutout: review fix -- a piece that no line separates from a nearby hole (it would already overlap it) stays ungrown instead of growing further in 2026-10-15 11:42:12 -05:00
matthewtrahan 877ffc9100 calibration: rebuild the cutout coupon's print files with the review fixes -- still no edge on more than two faces, PrusaSlicer time and filament unchanged 2026-10-15 11:42:12 -05:00
matthewtrahan fe90b6c857 cutout: review fixes -- each strip piece grows by moving its edges out (0.4-0.6 eps, its own distance) and clipping to a line separating it from each nearby hole, in place of slab overlaps, corner slides and corner pulls: those left pieces non-convex (a folded cap, 68 faces turned inward on a lattice wall) and opened sub-micron gaps; now every piece is convex, none reaches into a hole or leaves a gap, and the test checks for inward faces too 2026-10-15 11:42:12 -05:00
matthewtrahan c228633023 calibration: rebuild the pad and cutout coupons' print files for #223 -- the pad's predated the pad top-winding fix (1833 reversed faces, same triangles), the cutout's had flush pieces (951 shared edges); PrusaSlicer time and filament unchanged 2026-10-15 11:42:12 -05:00
matthewtrahan cc2a75dd17 cutout: a cut wall's pieces overlap instead of sitting flush -- slabs stacked at a cut, bands ending on a post's cap, bands meeting where a short wall's zone closes, corners touching across a strip side all shared welded edges (4-6 faces to an edge), which slicers that weld by position report as non-manifold (#223: 951 on the cutout coupon); now none, same printed shape 2026-10-15 11:42:12 -05:00
matthewtrahan c7d20908d7 surface: review fixes -- a NaN vertex (corrupt binary STL) gets a -Infinity floor, where a NaN floor unsorted the lists and the early exit returned 2 over a true 1; the test now warms each grid past the sort gate, so it checks the lowest-first path and not only the plain scan 2026-10-15 07:39:01 -05:00
matthewtrahan cf8eb08268 surface: sort a grid's lists lowest-first only once it has been asked enough to repay the sort -- sorting every short-lived region array slowed a dense mini's Suggest 5.3 -> 10 s 2026-10-15 07:39:01 -05:00
matthewtrahan cf0c950d1b surface: the lowest-height lookup walks each cell lowest-first and stops once nothing left can reach below the best -- a tall column scanned every surface stacked above it; same minimum, bit for bit 2026-10-15 07:39:01 -05:00
matthewtrahan 98c0d5a94d suggest: review fixes -- a ranking in flight is dropped (worker terminated) by whatever clears the list (new part, undo, reset), a message error falls back inline, and the test ranks a torus whose answer the gap really changes 2026-10-14 21:32:24 -05:00
matthewtrahan 0f9cd68cf5 suggest: rank in a Worker with the page's tunables -- a 250k-face figure froze the page for 14.5 s; now the longest frame is 17 ms and the ranking is the same, default or changed gap; inline when no Worker can run 2026-10-14 21:32:24 -05:00
matthewtrahan 662b6b3a8f import note: a file with negative parts says the walls inside one show in the slicer once it slices -- the export carries the negative part, and a slicer draws it over the walls in its cut until then (#104) 2026-10-14 21:25:19 -05:00
matthewtrahan 6d4fbb26b7 3mf: review fixes -- a coloured part's material table and the first slicer part no longer share resource id 5 (the slicer parts start past it), and the bed shift counts the slicer parts so a modifier reaching past the part stays on the bed; pinned with the interface crest on, which all three slicers still read as one two-part supports object 2026-10-14 21:25:19 -05:00
matthewtrahan 07bd5ca224 cli: a 3MF output carries a slicer's own parts back out the way the site does, in the separate form so a negative part can't cut the walls in its hole (#104); an STL output says it left the modifiers out 2026-10-14 21:25:19 -05:00
matthewtrahan 2fac7171f7 export: a 3MF with a slicer's own parts goes out as the file had it -- the part uncut beside its negative parts, modifiers and blockers, posed with it, for the slicer to cut again (#104); the fins and the saved session stay the cut part's, and opening the export here again cuts to the same part 2026-10-14 21:25:19 -05:00
matthewtrahan 2029c4b63a 3mf: a slicer's negative parts, modifiers and support blockers are written back beside the part, each its own kind with its settings verbatim (#104) -- Bambu/Orca and PrusaSlicer 3 as one assembly named in both configs (each reads its own, checked with all three slicers' command lines), PrusaSlicer 2 as triangle ranges of one mesh; never into the object holding the fins, since a negative part cuts every part of its object 2026-10-14 21:25:19 -05:00
matthewtrahan 1bcda45da7 render: review fixes -- keep drawing while the camera moves at all (the orbit's easing tail moves under OrbitControls' 1 mm 'change' threshold), and the fps count restarts after a pause 2026-10-14 21:14:50 -05:00
matthewtrahan 75c31cd2e4 render: draw while something may be changing (input, orbit easing, a mesh added or removed, a build landing) and every 500 ms otherwise -- idle went from 60 frames a second to 2 2026-10-14 21:14:50 -05:00
matthewtrahan 511d81fc91 drag: review fixes -- the paint record keys on the colour attribute itself, and the comment says which parts still shade every frame 2026-10-14 21:10:10 -05:00
matthewtrahan 35035da5df drag: a heavy part's live shade leaves frames between runs, and a repaint writes and uploads only the faces whose colour changed -- a ring drag on a 1.56M-face mini went 17 -> 48 fps; release still shades in full 2026-10-14 21:10:10 -05:00
matthewtrahan b044d5846e picks: reflow pick.js's header comment 2026-10-14 21:05:50 -05:00
matthewtrahan bc7e9ed52d picks: review fixes -- the vendored BVH is cached a year like occt and manifold, and pick.js's load-cost note stands on its own 2026-10-14 21:05:50 -05:00
matthewtrahan 601c18c665 picks: every Mesh raycast through three-mesh-bvh (vendored 0.9.15, MIT) -- a Draw hover on a 1.56M-face mini took 75 ms a pointer move, now under 1 ms with the same hits; the BVH builds on a big mesh's first pick 2026-10-14 21:05:50 -05:00
matthewtrahan 0a01443560 grids: review fixes -- a pierce found on the fine grid reports the one the old 64x64 walk met first (9% of pierces moved up to 1.5 mm, and callers trim the station nearest it), buildFins drops its seated part when done, gridsize's comment counts cells right 2026-10-14 20:30:08 -05:00
matthewtrahan d353ca302e grids: solidClearance walks the old 64x64 grid for a big wall triangle's box (thousands of fine cells were half a 512 mm build), seatedPartTris hands back one array per pose so its surface grid is built once, and one face per cell 2026-10-14 20:30:08 -05:00
matthewtrahan 6bd5cdc143 grids: size the surface and inside grids to the mesh, not a fixed 64x64 -- a cell's share of a dense part grew with its face count and every station's query scanned it (~80% of Auto on a 768 mm figure) 2026-10-14 20:30:08 -05:00
matthewtrahan 4dbb6fc094 cut: review fixes -- a cutter that will not load leaves the file open uncut with a note (and is retried next file) instead of refusing it, an inside-out negative is turned outward so it cuts rather than adds plastic, the shell/debris repair is for negatives only (the part is never changed without a word), and negatives that remove the whole part leave it uncut with a note 2026-10-14 20:21:26 -05:00
matthewtrahan 31228abb1d cut: a slicer's negative parts are cut out of the part on import, so the fins are built for what prints (#104) -- Manifold (manifold-3d 3.5.4, Apache-2.0, vendored, loaded only for a file with one); a scanned negative of closed shells plus sliver debris still cuts, a part or negative that is not a closed solid is said and left uncut; paint stays on the faces the cut leaves whole; the CLI bundle carries the WASM; the import note says how many were cut 2026-10-14 20:21:26 -05:00
matthewtrahan bb6d714d57 cut: WIP -- a slicer's negative parts cut out of the part with Manifold (manifold-3d 3.5.4 vendored, loaded on first use); not wired into the import yet 2026-10-14 20:21:26 -05:00
matthewtrahan f4166105e6 3mf negative parts: review fixes -- a PrusaSlicer 2 second instance (a wrapper over the first one's mesh) keeps its negative out (it read solid), a part placed twice is two extras rather than one merged shell, the CLI warns when it leaves one out, and a Bambu plate whose part ids collide is pinned 2026-10-14 20:21:26 -05:00
matthewtrahan fd6c962820 3mf: PrusaSlicer 3's part types (PrusaSlicer3_project.json) are read too, and the three slicers' own files are pinned -- a cube with a negative cube saved by Bambu Studio, OrcaSlicer and PrusaSlicer 3, stripped to the model and the part-type config 2026-10-14 20:21:26 -05:00
matthewtrahan b2bd24ef16 3mf: a slicer's negative parts, modifiers and support blockers/enforcers stay out of the part (#104) -- Bambu/Orca model_settings.config subtypes and PrusaSlicer Slic3r_PE_model.config volume ranges are read, and each comes back by kind beside the part: a PrusaSlicer negative volume was read solid into the part, a Bambu one (type other) was dropped as unknown; the import note says they are not in the export yet 2026-10-14 20:21:26 -05:00
matthewtrahan e2b8e846ba weld: review fixes -- fold the hash's high bits into the slot (a power-of-two micron grid piled into a few slots, 45x slower), NaN_KEY before its use, the edge-case test covers +-Infinity and float32-huge 2026-10-14 15:45:24 -05:00
matthewtrahan 33cbb2e695 tests: README lists weld.test.js 2026-10-14 15:45:24 -05:00
matthewtrahan 32141cf3aa weld: number-keyed hash tables, not string-keyed Maps -- a 1.5M-face part welded in 3.5 s on the page thread at load, now 0.5 s; same keys, same first-seen ids, identical topology 2026-10-14 15:45:24 -05:00
matthewtrahan 2667473892 nearface: review fixes -- the first pass walks only each ring's shell (a probe in a hollow sphere's middle paid the whole cube per ring), and the never-reached forced bucketing goes 2026-10-14 14:50:40 -05:00
matthewtrahan c8b4f98afe tests: README lists nearface.test.js 2026-10-14 14:50:40 -05:00
matthewtrahan c272fc2a34 tines: aim each tine through a grid, not a scan of every face -- biteDirsAt measured all faces for every tine (tines x faces), 60% of Auto on a 512 mm figure; nearestFaces gives the same faces, ties and order bit for bit 2026-10-14 14:50:40 -05:00
matthewtrahan 2ac92aa5ed 3mf colours: review fixes -- a paint string is copied on read (a scanned slice kept the whole decoded model file alive for the session), and a test that paint inside a Bambu object file (p:path) comes through 2026-10-14 14:31:54 -05:00
matthewtrahan e18334bca1 3mf: a painted part keeps its colours through fins + export (#236) -- Bambu/Orca paint_color and PrusaSlicer mmu_segmentation ride verbatim on the same triangles, core basematerials/colorgroup colours come back as one material table; the supports stay uncoloured 2026-10-14 14:31:54 -05:00
matthewtrahan 2cfd7c607d tines: review fix -- the spec says how much solid a moved end ran through apart from how far it came in 2026-10-14 13:42:33 -05:00
matthewtrahan f4e286aae5 tines: an end stops at the first solid -- the far probe (2x the reach) passed a part thinner than it and ran the tine through, and bisected back from a piece beyond a thin near one (cone/needle/tube X40: tine corners 0.3-0.5 mm into a thin edge at 0.2 layers); where the walk finds nothing the end is unchanged to the bit 2026-10-14 13:42:33 -05:00
matthewtrahan 6c3860ad79 wedges: review fixes -- the test walks each wedge's tines back from its end (36-vert chunks ran misaligned past the blade and missed a quarter of portal's), and the spec's count is portal's real 41 -> 42 2026-10-14 13:15:08 -05:00
matthewtrahan 97c6c65b30 wedges: tines follow the layer height -- a wedge's tines were always 0.2 tall with the 0.2 reach, a third of a 0.6 layer, which the slicer drops or merges (portal X45 at 0.6: 32 tines, now 0.6 tall) 2026-10-14 13:15:08 -05:00
matthewtrahan 8c8b50b137 section: review fixes for the sheet grab -- mouse and pen only (touch keeps one-finger orbit), the press still reaches the page so open menus close, Ctrl+click cancels rather than grabs, hover raycasts once a frame, the grab cursor survives Draw's hover, the drag stops at the part's reach; the toolbar clears whichever left-pane card is beside it 2026-10-14 13:07:13 -05:00
matthewtrahan 7e0415ed19 section: drag the sheet itself to push the cut (outside the part's outline; it brightens and shows a grab cursor), and the view toolbar moves bottom-left beside the rotate panel, smaller, frosted glass 2026-10-14 13:07:13 -05:00
matthewtrahan af89d31070 view toolbar: review nits -- a badge names its popover (aria-controls), and Esc folds the open popover away 2026-10-14 13:07:13 -05:00
matthewtrahan ab7996a94d section: the Section badge moves to a new view toolbar along the bottom of the 3D view -- one popover of key settings at a time, a click on the open badge turns the tool off; built so more view tools can join it 2026-10-14 13:07:13 -05:00
matthewtrahan d91f47c559 section: the handle's rings stay hidden until the section is on -- attached to the hidden handle, they drew at the origin over the empty start page 2026-10-14 13:07:13 -05:00
matthewtrahan b07b12ddd0 section view: review fixes -- on touch the arrow and a ring could both grab one press (the rings now stand down on the arrow's own mouseDown, and a cancelled touch restores them); Shift + scroll pushes the cut 1 mm a notch, since the arrow hides when you look square at the cut; the selection, hover and draw-preview overlays stay out of the glass pass 2026-10-14 13:07:13 -05:00
matthewtrahan 7b7a3e5217 section view: one handle, a ghost, and a home in Display -- an arrow pushes the cut and two rings tilt it (no Move/Turn modes); Ghost (default) draws the cut-away half as glass, Hide leaves it out; it starts square to whichever of the part's own axes faces the camera, so a bore seen from the side opens lengthwise; a Section button in the Display header with Ghost/Hide, Flip and Re-aim under it replaces the rotate-panel checkbox 2026-10-14 13:07:13 -05:00
matthewtrahan 1a2b3effbf section view: review fixes -- a tap on the plane's handle no longer falls through to a pick (the handle clears its axis on release before app.js reads it, so the press is remembered); Move shows one arrow along the cut's normal; the cut turns and reseats with the part 2026-10-14 13:07:13 -05:00
matthewtrahan 736cf9e5d1 section view (#250): a plane you move and turn hides the part and its supports on one side, so the inside of a bore can be seen and drawn on -- clicks reach only what is shown, the cut faces paint flat slate, Flip / X / Y / Z snap it through the part; view only, never exported or saved 2026-10-14 13:07:13 -05:00
matthewtrahanandPer Hjort 813a01f537 nozzle: a free edge's outermost row steps in as the tip widens -- at 2.0 the 3 mm tip and its 2.5 mm tines hung 1.2 mm past a cube's side (X30), tabs out of the wall instead of under the part
Co-authored-by: Per Hjort <35040883+HjortCreations@users.noreply.github.com>
2026-10-14 12:30:30 -05:00
matthewtrahanandPer Hjort 877111da59 nozzle: review fixes -- the tine reach grows past a wider contact tip (sphere at 45deg: 6 tines at 2.0, now 26; 30 at 0.4), walls stop at 6 mm so a row never fuses, nozzles to 2.0
The reach is measured from the wall's centre, so a tip wider than 0.4's 0.6
swallowed the 0.5 reach and a curved underside lost its tines; the extra
half-tip is added to it (0.15 at 0.6, 0.3 at 0.8, 1.2 at 2.0; 0.4 and finer
unchanged). A wall over 6 mm -- half the 12 mm row spacing -- fused rows into
one block (3.0 x 8 lines: 6.7 kg on a 252 g plate), so walls and wedges cap
there, the page offers only the Wall lines that fit the nozzle, and the
nozzle stops at 2.0 (2.5's two-line wall is already 6.25). tests: every
offered nozzle x lines stays under half the row spacing; the sphere keeps 70%
of its 0.4 tines at 2.0 with nothing inside the part.

Co-authored-by: Per Hjort <35040883+HjortCreations@users.noreply.github.com>
2026-10-14 12:30:30 -05:00
matthewtrahanandPer Hjort e44cb1d846 nozzle: large-format sizes 1.0-2.0 mm, and a nozzle guide -- the same scaling rule (a 2.0 nozzle builds a 5 mm wall); layer height stays capped at 0.6
From Per Hjort's #210, which took nozzles up to 3 mm (2.0 here, see the review fix). Layer height stays at
0.6: the gap, flanges and pad are fixed heights tuned for thin layers. The
guide (docs/NOZZLE.md, adapted from #210's) lists the widths per size, the
limits (thicker walls fit fewer places) and what to check in the slicer. 0.4 is
unchanged (sweep vs main: no mesh changed).

Co-authored-by: Per Hjort <35040883+HjortCreations@users.noreply.github.com>
2026-10-14 12:30:30 -05:00
matthewtrahan e15f31548e tines: review fixes -- the reach multiplier stops at 3x (a slicer plugin's own layer height can pass the site's 0.6), and a test that a 0.6-layer tine's snapped top is clear of the part at its mid-layer 2026-10-14 09:32:07 -05:00
matthewtrahan 9d4a0eeddc tines: the reach follows the layer height -- at a fixed 0.5 mm a thick layer found no solid under a shallow underside and built every wall there with no tines
The reach probe sits at the tine's mid-height, half a layer under the
underside, so it only finds solid when reach * tan(slope) > layer / 2: the
cutoff was ~17deg at 0.3 mm layers, ~22 at 0.4, ~31 at 0.6. The M4 front
upright had 223 tines at 0.2, 117 at 0.4, 53 at 0.6; buster upright none at
0.4. The reach now keeps the 0.2 layer's ratio (tineReach * max(1, layer/0.2)):
228 / 220 and 15 / 10. 0.2 and thinner are unchanged (sweep vs main: no mesh
changed). Found checking #210's large nozzles: not the nozzle, the layer.
tests: a tilted block at 20 and 30deg gets as many tines at 0.3/0.4/0.6 as at 0.2.
2026-10-14 09:32:07 -05:00
matthewtrahanandPer Hjort 103f61f337 wall lines: review fixes -- a thick wedge reads its edges' underside, not just the centreline (0.45 mm into a tilted cylinder at 8 lines); a squat brim stays under half the row spacing; a session saved before Wall lines loads at 2
The wedge fix only runs for a blade thicker than the tuned 1.2 mm, so 2 lines is
unchanged (sweep vs main: no mesh changed). tests: cylinder and tube at X45 with
8-line wedges have nothing inside the part; the brim cap at 0.8 / 8 lines.

Co-authored-by: Per Hjort <35040883+HjortCreations@users.noreply.github.com>
2026-10-14 08:41:44 -05:00
matthewtrahanandPer Hjort e40a63341f nozzle: a Wall lines setting (2/4/6/8) -- thicker walls, wedges and braces for a tall part or a big printer; the tip and tines stay one line
From Per Hjort's nozzle profiles (#210), ported onto web/nozzle.js. Lines
multiply the structural widths (wall, wedge; a brace rib is never thinner than
the wall). The feet move out with the wall's face, and a neck into the tip that
would lean flatter than 55deg gets the height to stand at 55. 2 lines is the
tuned wall: sweep vs main unchanged (no mesh changed). A thicker wall fits fewer
places, so a tight part can lose a wall or two at 8 lines; the readout reports
them. A setting of the part (undoable, saved with a session), sent to the Worker
in opts.tunables.wallLines. The plugins build 2 lines.

Co-authored-by: Per Hjort <35040883+HjortCreations@users.noreply.github.com>
2026-10-14 08:41:44 -05:00
matthewtrahan 93c36f9561 plugins: gap review fixes -- Blender's float32 gap at 0.4 is in range, Onshape's gap bounds are the site's 0.1-0.4, Cura README 2026-10-14 07:54:03 -05:00
matthewtrahan 93bb5565f4 plugins: the Material option becomes the site's Support gap -- PLA's pad numbers, a 0.1-0.4 gap field in every dialog, Cura's Match Cura and Onshape's PLA/PETG/Custom go 2026-10-14 07:54:03 -05:00
matthewtrahan b625eedd30 web: drop the PLA/PETG Material dropdown -- PLA's numbers stay the defaults, PETG's wider gap is the Support gap field's
The dropdown only moved the Support gap (0.2 -> 0.3, already its own field), the
Sure hold pad's thickness and tack, and the grams density (2%). Default output is
unchanged (sweep vs main: no differences). Startup now reads the Support gap field
into PROP.gap, which the material's reset used to cover. The plugins keep their
material option until their own PR; options.test.js lists it as plugin-only.
2026-10-13 19:14:53 -05:00
matthewtrahan 1f605c5a5c downhill: find the top edge by following the climb, not one straight step
On a curved slope (a spiral ramp's underside) a straight 1 mm step uphill cuts
across the curve and leaves through the side edges, which then read as the top:
the ramp got one line from a misplaced seed. The climb is now followed in
quarter steps, re-aimed each time, and seeds are ordered across the top edge's
own downhill direction. The ramp gets an arc down each edge.

Sweep vs main (NOCHECK): 805/864 byte-identical, 0 blocking.
2026-10-13 16:24:35 -05:00
matthewtrahan 0339d9b596 downhill: review fixes -- re-pointed tine captures, try/finally, hashed join check
- raceAgainst re-points each kept wall's `caps` into the rebuilt capture: after
  a raster swap the downhill race sliced the wrong tines (and the judge read
  the wrong lowest tine)
- judgeDownhill restores globalThis.__TINECAP in a finally, and classifies once
- downhillLines finds an earlier line through a plan hash, not a scan of every
  station
- the downhill race no longer carries rasterRegions over (it overcounted)
- tines.js says the capture seam is no longer test-only; a test renamed to what
  it checks

Sweep vs main (NOCHECK): 803/864 byte-identical, 0 blocking.
2026-10-13 16:24:35 -05:00
matthewtrahan cb460b96ce spec: downhill walls -- seeds, stops, the race and the whole-build check (#25) 2026-10-13 16:24:35 -05:00
matthewtrahan f93f29ed51 engine: downhill walls -- walls that run down an overhang and follow it to the plate (#25)
prop/downhill.js traces the overhang's steepest descent from each end of its
top edge and every 12 mm between. On a flat slope that is a straight line; on a
curved one the wall bends with it. Across a wall that runs downhill the surface
is level, so its top settles and clears the part on both flanks -- walls laid
along a slope's edges (#125's curve paths) failed the clearance probe at every
station on the #25 part.

Auto races them per region against the other placements (raceAgainst, 3%
margin, at most 1.5x the weight). A downhill wall with any vertex inside the
part is dropped first: a flank flush with a part face at the region's top edge
read as clear (lbracket Y20 on the plugin path). Then fins/downhill.js builds
the part without them too and keeps the downhill build only if it holds at
least as much overhang, grips no higher and keeps every wedge -- wedges, short
walls and the fill pass build around whatever the race kept, and the race
can't see them.

buildProps leaves them off unless asked (opts.downhill: true); buildFins in
Auto/Full turns them on and judges; downhill: false builds without them.

covered. Sweep vs main (NOCHECK): 802/864 byte-identical, 36 cases gain >2 pts
coverage, 0 blocking; arch/cone/needle X40 goldens move (75/92/92 -> 100%).
The torus X45 squat-pass test builds with downhill: false -- downhill walls
take that ledge over and hold more of it (70 -> 75%).
2026-10-13 16:24:35 -05:00