Commit Graph
2370 Commits
Author SHA1 Message Date
aj aea5e9f617 Merge remote-tracking branch 'origin/master' into claude/avalonia-port-next-tasks-f1f6b6 2026-11-13 20:25:34 -05:00
ajandClaude Opus 5.5 267c7e9453 Merge M09 selection into the Avalonia undo work
Combine the Edit menu (Undo, Redo, Select All) and restore the whole
part selection by index after an Undo or Redo, now that the canvas
selects several parts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 20:25:15 -05:00
aj d6a551fdea Merge branch 'worktree-agent-afafee97ace7d9df4' into claude/avalonia-port-next-tasks-f1f6b6 2026-11-13 20:22:37 -05:00
aj e975244263 Merge branch 'worktree-agent-aec6db3a2c226fa2a' into claude/avalonia-port-next-tasks-f1f6b6 2026-11-13 20:22:37 -05:00
ajandClaude Opus 5.5 dc8023f076 feat(avalonia): select parts and cut-offs by click, window and Select All
The plate view routes left and right clicks to the shared Select tool,
draws the selection, the blue/green selection window and selected
cut-offs as WinForms does, pans with a middle drag and handles Escape.
Edit > Select All (Ctrl+A) is added, and the status bar shows the tool
and the selection's bounds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 19:30:50 -05:00
ajandClaude Opus 5.5 313b5f57d6 feat(desktop): add a toolkit-neutral plate tool and selection model
PlateToolManager keeps one active tool with the WinForms action rules
(Escape cancels, then returns to Select, then resumes the ended tool) and
status text. SelectTool selects by click, Ctrl+click and window
(contains/intersect), takes common-line groups together and picks
cut-offs by their strokes. PlateHitTester hit-tests the shared display
geometry; PlateSelection reads and sets by part index.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 19:30:47 -05:00
ajandClaude Opus 5.5 d0654d267c feat(avalonia): export plates, view in CAD and nest reports
File > Export Plate... and Export All Plates... write the shown plate (each
plate in turn, shown while its file is chosen; cancel or a failure stops
the rest) as DXF, the view's image, the placement list or SVG, chosen by
the picked file's extension, under the WinForms suggested names. The image
is the plate canvas drawn by its Skia painter at the screen's density, PNG
or JPEG. Plate > View in CAD writes <nest>-P<n>.dxf to the temp folder and
opens it in the system's CAD program. File > Nest Report... writes the PDF
to a private temp folder and opens it in the system's PDF viewer, which
saves and prints it (older viewed reports are removed); File > Export Nest
Report... saves it to a chosen file. Reports refuse while Auto Nest runs on
the nest and are written off the UI thread from a detached snapshot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 19:28:39 -05:00
ajandClaude Opus 5.5 7792badac3 feat(desktop): report opener failures and drop bitmap plate exports
ExternalFileLauncher.OpenAsync waits for xdg-open or open without blocking
and explains a failed exit code (no program set up for the file type, file
not found), which the shell-less platforms otherwise swallow. File > Export
no longer takes .bmp as an image: no cross-platform encoder writes it, so
the image formats are .png, .jpg and .jpeg.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 19:28:39 -05:00
ajandClaude Opus 5.5 ad6ffa1fda feat(avalonia): undo and redo nest edits from the Edit menu
Edit > Undo/Redo name the next step and follow the active tab's history;
Ctrl+Z, Ctrl+Y and Ctrl+Shift+Z undo the nest unless a text box has focus.
A restore keeps the plate, zoom, pan and selection. Auto Nest's commit is
one undo step and blocks Undo on its nest while it runs. DEBUG builds warn
about edits made outside a change scope.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 19:27:07 -05:00
ajandClaude Opus 5.5 098e1d92a7 refactor(desktop): share plate export, file launching and nest report writing
Move the toolkit-neutral parts of File > Export/Export All, Plate > View
in CAD and the nest report commands into OpenNest.Desktop: export formats
and suggested per-plate file names (now free of characters any platform
refuses), the placement list, DXF/SVG writing with the view image left to
the front end, opening a file in its associated program on Windows, macOS
and Linux, the report file name check, capture with catalog density, the
machine's thickness name and saved cut-time settings, and viewed-report
temp folders. WinForms calls the shared code; its behaviour is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 19:27:07 -05:00
ajandClaude Opus 5.5 9c0a543d79 feat(desktop): give each nest tab its own undo history
NestTab starts a NestUndoRecorder once the trailing empty plate is in
place, so opening is not an edit. Modified now follows the history's save
point and unscoped edits (undoing back to the saved state clears it), and
SaveAs records an unscoped edit before marking the save point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 19:27:07 -05:00
ajandClaude Opus 5.5 ef7ebd2f44 feat(avalonia): add Tools > Options on the shared Options model
Auto-size factor, colour scheme, cut planning effort, clone push
placement, new nest on startup and the fill strategy grid save to the
user settings both apps share and apply at once (open nests take the new
scheme's colours); the saved fill strategies apply at startup. Set /
Change Server writes storage.json keeping the storage mode, and the next
server request uses it; Save Feed URL and Include development builds
save for the updater. MaterialLedger stays in the WinForms app: its API
key is DPAPI-protected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 19:25:15 -05:00
ajandClaude Fable 5.2 07f30c1236 fix(engine): settle best-fit pairs sideways so they close to the part spacing
The pair search slid part 2 in from offsets on a 0.25 step grid, so a pair
that locks in a corner (two interlocking channels) stopped up to a step short
of the tightest fit. Each resting position is now also slid sideways, both
ways, and the new resting positions join the candidates.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-13 18:25:25 -05:00
ajandClaude Opus 5.5 9663f341dd refactor(desktop): share undo recording and stepping as NestUndoRecorder
Scopes, the fingerprint safety net, Undo/Redo stepping, the unsaved check,
identity carry-over and the Edit menu labels move from EditNestForm to
OpenNest.Desktop. The WinForms window keeps only its rebinding swap-in and
its guards; behavior is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 17:44:39 -05:00
ajandClaude Opus 5.5 fc5c2c9469 refactor(winforms): run the Options form on the shared Options model
Same settings, messages and apply order; the form only maps controls to
Properties.Settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 17:43:20 -05:00
ajandClaude Opus 5.5 9a55b00d2c feat(desktop): share the Options settings model with both desktop apps
DesktopOptions reads and writes the Tools > Options values under the
WinForms user-setting names, with the clone placement choices, the fill
strategy grid rows and DisabledStrategies parsing/applying, and the
server URL and update feed URL validation and messages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 17:43:20 -05:00
ajandClaude Opus 5.5 09357ca95d feat(avalonia): show the dark OpenNest workspace when no nest is open
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 17:33:42 -05:00
ajandClaude Opus 5.5 7f1cff301a feat(avalonia): create new nests from File > New, Ctrl+N, New and +
Move the File > New rules into OpenNest.Desktop (NewNestSource): nest
defaults, the default machine with its clamps and support grid, Made By
and the year's next name, from the nest server in Database mode and the
counter both apps keep in user-settings.json otherwise. The WinForms
factory now delegates to it.

The Avalonia app opens a new nest in a tab with no file (NestTabs.Add),
off the UI thread and one at a time, and its nest view keeps an empty
last plate as the WinForms nest window does, so a new nest shows Plate 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 17:31:18 -05:00
ajandClaude Fable 5.2 9b7082e92f fix(clone): keep Shift+click copies at the part spacing
The coarse bounding-box pass only stopped at obstacles whose box lay in
the push path, so a copy could drop past a neighbor beside the path and
end inside its spacing. A box push now also stops at an obstacle nearer
than the spacing to the side of the path.

A push ignores a part the copy starts on, so a settle could slide out of
that part and stop clear of it yet inside its spacing. SettlePlacement
now prefers a push order that keeps the part spacing, and a named order
that ends too close falls back to the other order.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-13 15:43:47 -05:00
ajandClaude Fable 5.2 32fc3cad97 fix(core): color drawings from the classic palette when a scheme has no part colors
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:54:48 -05:00
ajandClaude Fable 5.2 3b182b8b57 fix(training): send the schema migration as raw SQL again
The formatter rewrote ExecuteSqlRaw to ExecuteSql, which passes the
column name and type as parameters; SQLite rejects that and the bare
catch hid it, so older databases never gained their missing columns.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:54:48 -05:00
ajandClaude Fable 5.2 bc0136e3f7 refactor(core): move cut-offs into OpenNest.CutOffs
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:42:45 -05:00
ajandClaude Fable 5.2 c8e899c493 refactor(core): move common lines into OpenNest.CommonLines
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:40:26 -05:00
ajandClaude Fable 5.2 cd5a400a22 refactor(core): move clamps into OpenNest.Clamps
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:38:20 -05:00
ajandClaude Fable 5.2 70ca4c4be6 refactor(core): split Plate into partial files by concern
Moves whole members verbatim into Plate.CommonLines.cs, Plate.Clamps.cs, Plate.CutOffs.cs, Plate.Transforms.cs and Plate.Sizing.cs. No behavior or API change.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:32:51 -05:00
ajandClaude Fable 5.2 b77b3b7a33 refactor(core): swap an immutable part palette instead of mutating Drawing statics
Drawing.PartColors (a public array aliasing the active scheme's), Drawing.UseGoldenAngleColors and a non-atomic colour counter were process-global display state. PartPalette now holds a copy of the colours and the golden-angle flag; PartColorPalette.Current/Use swap it as a whole, Drawing.GetPartColor/GetNextColor read it, and the counter increments atomically. Colours shown are unchanged.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:20:22 -05:00
ajandClaude Fable 5.2 986167a411 refactor(core): refresh Drawing's derived state through ProgramChanged
Area and the canonical angle were refreshed together only by the Program setter; an in-place program edit needed two separate calls, and UpdateArea kept a stale Area when no material was left. ProgramChanged is now the single entry point (the setter calls it), a program with no material or a null program gives Area 0, and UpdateArea/RecomputeCanonicalAngle are private.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:20:22 -05:00
ajandClaude Fable 5.2 dec685361c refactor(core): make Math and Geometry Core's bottom layers
Move ContourSampler to OpenNest.CNC and DrawingAligner with its
AlignmentResult types to OpenNest.Converters: they were the only Geometry
files importing CNC and Converters. Their tests move with them.

CoreLayeringTests scans the Math and Geometry sources against the type
names reflection finds in Core, so neither can name a higher layer again.
Geometry keeps six root-namespace types on an explicit allowlist, and the
files declaring them may reference only Math and Geometry.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:12:13 -05:00
ajandClaude Fable 5.2 9b893c7a09 refactor(core): remove Plate.HasOverlappingParts
Its last callers were four strategy tests; they now use
PartOverlapChecker.FindOverlappingPairs, which also reports
contained and stacked parts.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:11:37 -05:00
ajandClaude Fable 5.2 e5d4337681 fix(core): report overlapping pairs through PartOverlapChecker
The console overlap check and the MCP check_overlaps tool counted
crossing points, so a part contained in or stacked on another reported
no overlap. Both now list pairs from PartOverlapChecker.FindOverlappingPairs,
which uses the Intersects verdict and skips cut-off parts.

Plate.HasOverlappingParts stays for now: two test files outside this
change still call it.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:10:26 -05:00
ajandClaude Fable 5.2 a451cf5ef3 fix(core): narrow the perimeter-build catch to geometry failures
BuildPartPerimeter swallowed every exception. It now guards a missing
program and an outline that forms no shape, and catches only geometry
failures; a null perimeter still makes a cut-off exclude the part's whole
bounding-box span.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:10:26 -05:00
ajandClaude Fable 5.2 32edc18ede fix(core): stop a part turning a program its offset copies share
Part.CloneAtOffset hands the copy the source's Program instance. The copy
cloned before rotating, but the source still owned the program, so rotating
the source turned the program under every tiled copy while their location
and bounds stayed put.

Program now carries a sticky SharedByParts flag that CloneAtOffset sets, and
a part copies its program before rotating when it does not own it or the
program is shared. The flag lives on the program rather than the part so a
restored cutting state, which reinstates ownership field for field, cannot
re-alias a shared program. Unrotated copies keep sharing one instance, which
the fill and overlap caches key on.

Update, ApplyLeadIns and ApplySingleLeadIn install a fresh program and now
own it, saving a needless copy on the next rotate.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:09:28 -05:00
ajandClaude Fable 5.2 febeb76836 refactor(core): remove unused Entity.MoveTo and point-based OffsetEntity
Nothing called MoveTo on a geometry entity or the OffsetEntity(distance,
point) overload. Shape and Arc threw NotImplementedException for them, and
the Line and Polygon versions were wrong and untested. Remove the abstract
declarations and every override; the OffsetSide overload stays.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 19:04:08 -05:00
ajandClaude Opus 5.5 c8e1b97786 fix(ui): sign new nests with Made By instead of on viewing Nest Info
Nest Info filled a blank Made By with the current user every time it
opened, so pressing OK on an existing nest's info (from a tab or Saved
Nests) signed someone else's nest. The author is now stamped once when a
nest is made (File > New, drawing set Make Nests, BOM import), and Nest
Info shows the stored value as is, leaving a blank one blank.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 18:21:22 -05:00
ajandClaude Opus 5.5 5d00715948 chore(help): ship opennest-help v0.8.0
v0.8.0 documents the drawing library's Filter dialog and its Size and Holes
columns (b9fc618a), with recaptured library screenshots and a new
library-filter topic. The zip's SHA-256 was checked against the release's
published hash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 17:51:23 -05:00
ajandClaude Opus 5.5 e6d438629f feat(cutting): slice slugs the support grid can't hold level
On an enclosed machine a cutout slug that tips once cut free can stand up
above the sheet and catch the enclosure door when the pallet changes. The
head already keeps off cut cutouts, so this is about clearing the door, not
the head.

Cutting Settings > Cutouts > "Slice slugs the support grid can't hold
level" (CuttingParameters.SliceTippingSlugs, off by default, saved per
machine thickness and written only when on) makes Plan Cutting cut each
such slug along the bed's contact lines (grid rows and columns, slat center
lines) before the cutout, so no piece keeps a contact and the pieces drop
between the supports. Each slice stops a kerf short of the cutout, so the
pieces stay attached until the cutout's own kerf frees them together. A
slug the bed holds level, or one on no contact, is left whole; a cutout
holding another part or another of its part's cuts is never sliced.

Slices are break cuts emitted right after the drawing's own break cuts,
pierced on themselves and led straight back to their start. The
released-contour proof now leaves out straight break cuts lying wholly
inside one of the part's closed holes, since the grid cells they free are
scrap; break cuts in material still take part. The plan fingerprint only
changes when the setting is on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 17:04:27 -05:00
ajandClaude Opus 5.5 b9fc618a50 feat(library): filter the drawing library by thickness, size, holes, date and customer
Finding a part on the nest server meant scrolling 40k drawings: the library
could only match an exact thickness or customer and knew nothing about a
drawing's size or holes. The library browser gets a Filter dialog with
inclusive ranges, and the query API takes them.

The server never parses packages and stays off IO, so the server worker now
measures each package beside its nest jobs (bounding sides, net area, closed
cutouts inside the outline) and stores the summary keyed by package hash
(schema v19). Identical geometry is measured once, an unreadable package is
recorded once instead of retried forever, and size or hole limits match only
measured drawings. Thickness ranges compare in inches across units and keep
the library's rule that a drawing saved without a thickness suits any.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 16:47:51 -05:00
ajandClaude Opus 5.5 1382d00496 chore(help): ship opennest-help v0.7.3
The guides now use the regrouped File menu labels from ecd0bba4 and show a
recaptured File menu. The release also carries the earlier unreleased guide
updates for part printouts, plate list delete/duplicate and clone push
placement, all of which are on master.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:15:09 -05:00
ajandClaude Opus 5.5 314644b74b fix(ci): point the PDF acceptance area at the renamed report tests
ecd0bba4 removed File > Export Nest Report..., so its cancel test went
away and three report tests were renamed for the viewer path. The Windows
acceptance manifest still required the old names and failed with "expected
at least 1 cases, found 0" although every test passed. List the current
names, and add the two viewer tests now that the viewer is the only way to
get the PDF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:11:41 -05:00
ajandClaude Opus 5.5 ecd0bba4eb refactor(file-menu): regroup the export and report commands
The File menu ran six output commands together with no separators, and
"Export" / "Export All" didn't say what they exported. Group them by what
they produce:

- Save Copy as .nest File... (was Export .nest...) moves next to Save As,
  since it writes the nest file rather than exporting a plate.
- Export Plate... / Export All Plates... (were Export / Export All) get their
  own group and the "..." their save dialogs call for.
- Nest Report... / Part Printouts... (were View ...) form a reports group.
- Storage Mode... gets its own separator above Exit.

Export Nest Report... is removed: the report viewer already has Save As
(available even without WebView2), so it was a second path to the same PDF.
Its guard and failure tests now drive the viewer path, and the atomic-write
test calls WriteNestReport directly. The Avalonia prototype's matching
command is renamed too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 08:41:12 -05:00
ajandClaude Opus 5.5 755f021092 feat(reporting): dimension part printouts like the Shape Library
A part printout showed the part but not its size on the drawing, so the
operator had to read the table to know which way was which. Each page now
draws the overall X extent below the part and the Y extent to its right,
as the Shape Library does: arrows, a boxed label and extension lines that
stop 6 pt short of the outline itself rather than its bounding box.

Each dimension line moves out far enough to keep its label 14 pt clear of
the part (a wide label centered on an 18 pt line nearly touched it), and
the part and its dimensions sit 28 pt inside the drawing border, double
the old padding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 08:02:09 -05:00
ajandClaude Opus 5.5 72e16139ae feat(reporting): name the thickness on part printouts
The nest report already leads its thickness with the machine config's
Name / Gauge; the part printout's THICKNESS cell now does the same
(16 ga - 0.0598"), from the same lookup in the desktop.

Thickness names are typed into the machine config, so both writers now check
them against the bundled font's Latin-1 limit like other free text, instead
of failing partway through rendering.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 07:51:40 -05:00
ajandClaude Opus 5.5 2f3f105a5e feat(machine-config): name blank standard thicknesses on open
Thicknesses saved before the auto-fill kept a blank Name / Gauge until someone
edited their value, so their nest reports showed only the decimal. Opening
Machine Configuration now names every blank thickness that matches a standard
gauge or plate fraction and marks the form changed, so closing offers to save
them. Thicknesses matching none stay blank, and once saved a reopen finds
nothing to fill and does not ask again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 07:25:41 -05:00
ajandClaude Opus 5.5 35d77239b9 feat(machine-config): fill a blank thickness name from the standard gauges
Reports now take a thickness's name from the machine config, so a blank
Name / Gauge leaves the report with just the decimal. Machine Configuration
now fills a blank name from the standard steel gauge or plate fraction table
when the thickness value changes, and keeps following the value while the
name is still the old value's standard one; a typed name is never replaced.
A new thickness starts named for its default 0.25 (1/4").

Existing blank names are not filled on open, so viewing a machine never marks
it dirty; editing the value fills them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 07:25:41 -05:00
ajandClaude Opus 5.5 76e1acbc51 fix(reports): take the thickness name from the machine config
Each machine thickness already has a Name / Gauge field the shop fills in, so
the report now shows that name instead of guessing one from the standard
gauge table. It is matched the way the machine cutting defaults match the
nest's material, grade and thickness; a thickness without a name shows just
the decimal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 07:25:40 -05:00
ajandClaude Opus 5.5 21c1e0f2c7 feat(reports): drop the Units row from the summary
Every size, thickness and weight on the report already carries its own unit,
so the summary's Units row only repeated them and took a header line from the
part cards. The plate pages' ruler note still names the units, since ruler
numbers are bare.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 07:25:40 -05:00
ajandClaude Opus 5.5 d2da7396ce feat(reports): move generated time to the footer and name standard thicknesses
The generated date sat among the summary's report details and printed a UTC
offset nobody on the shop floor reads. It now goes in every page's footer,
left of "Page X of Y", in the computer's own time zone without the offset.

The thickness now leads with its gauge or plate fraction ("16 ga - 0.0598 in")
when it matches one, as the thickness box lists it. Reporting references Core
only, so the desktop looks the name up in StandardThicknesses and passes it on
the snapshot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 07:25:40 -05:00
ajandClaude Opus 5.5 696e0bdac6 feat(reporting): print one-page part printouts from the nest
Shops used CutSend to get a part printout (the part drawn to fit a Letter
page over a details table) because OpenNest had no way to make one. File >
View Part Printouts prints every part drawing of the nest, and the drawing
list's View Part Printout prints one; both open the report viewer to save
or print.

Cut length and pierce count walk the program as it is cut, so etch marks,
tab spans and display-only moves add neither, a tabbed cutout counts one
pierce per piece, and breakoff and common-line cuts count. The drawing list
item reaches the main window directly so nests made by BOM import get it
too. Rendering shares the nest report's lock, fonts and Latin-1 limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 07:10:56 -05:00
ajandClaude Opus 5.5 f146cf63f5 fix(avalonia): keep default view toggles out of settings and copy boxes for drawing
Write PlateViewDrawRapid/PlateViewDrawBounds only when changed from the default
or already saved, as the WinForms settings provider does, so a later default
change still applies. Give the render thread a copy of a broken common-line
part's box, and prune the label-point cache with the part paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 22:18:14 -05:00
ajandClaude Opus 5.5 8f0bd24534 docs: note the Avalonia canvas draws from the shared plate geometry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 22:18:14 -05:00