Python tool that finds drawings resembling a hand sketch, photo or MS Paint outline. It indexes the OpenNest server's drawing library (read-only) and/or DXF folders, compares DINOv2 embeddings of normalized renderings across all 8 rotations/mirrors, and writes an HTML page of the closest matches with an optional overall-size filter. train.py fine-tunes the embedding contrastively on synthetic sketches of the library itself (no labelling); evaluate.py measures recall on held-out drawings or a folder of real sketches. On 40,757 server drawings, held-out synthetic sketches find the right shape in the top 20 75% of the time, up from 18% zero-shot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
12 KiB
OpenNest agent instructions
Shared instructions; keep CLAUDE.md as the thin @AGENTS.md import.
OpenNest is a .NET 8 Windows CNC-nesting application with cross-platform libraries.
Working rules
- Prefer Roslyn Bridge MCP for symbols, references and diagnostics when available; fall back to text search.
- Use
varfor locals and namespaces matching project directories. Follow.editorconfig; format only changed C# files withdotnet format OpenNest.sln --include <paths>, then repeat with--verify-no-changes. On Linux, prefix both commands withEnableWindowsTargeting=true. - Keep instructions concise: commands, boundaries and non-obvious safeguards, not class inventories or session history. Update affected instructions and user-facing docs with behavior/build changes; put detailed contracts in
docs/. User guides and their screenshots live in the separateajisaacs/opennest-helprepo: update or recapture them when a UI change alters a documented screen, and never rename aHelpTopicsID. - Never commit design specs, implementation plans, progress notes or temporary benchmark reports. Keep working records under local, ignored
.hermes/plans/or.hermes/progress/; retain reusable verification procedures indocs/. - Keep vendor manuals/full-text extracts out of source control unless redistribution is authorized. Write project-specific behavior summaries with citations, separating controller rules, machine macros and unconfirmed behavior.
Build and test
# Full solution: Windows
dotnet build OpenNest.sln
# Cross-platform suites: run independently on Linux/macOS/Windows
# Use Release for routine runs; use Debug explicitly for DEBUG-only work counters.
dotnet test OpenNest.Tests/OpenNest.Tests.csproj -c Release
dotnet test OpenNest.Engine.Tests/OpenNest.Engine.Tests.csproj -c Release
dotnet test OpenNest.IO.Tests/OpenNest.IO.Tests.csproj -c Release
dotnet test OpenNest.Desktop.Tests/OpenNest.Desktop.Tests.csproj -c Release
dotnet test OpenNest.Server.Tests/OpenNest.Server.Tests.csproj -c Release
dotnet test OpenNest.FrontEnd.Tests/OpenNest.FrontEnd.Tests.csproj -c Release
# Windows runtime tests
dotnet test OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj
After changing planning, contour preparation or geometry checks, run the problem-nest corpus (Category=ProblemNests, opt-in via OPENNEST_PROBLEM_NESTS_SERVER); no plate may rank below its baseline. Keep desktop-dependent tests in OpenNest.WinForms.Tests, never add a WinForms reference to OpenNest.Tests. Optional CHR fixtures use local OpenNest.Tests/test-config.json and skip when absent. On Linux, build Windows projects with -p:EnableWindowsTargeting=true; this is not Windows runtime verification. The headless console builds independently with dotnet build OpenNest.Console/OpenNest.Console.csproj.
Releases: follow the release procedure and scripts/Publish-Windows.ps1; workflow artifacts are candidates, not published releases. GitHub (ajisaacs/OpenNest) is the primary repository; Gitea is a read-only backup mirror.
Project map and boundaries
OpenNest.Core: domain (Nest -> Plate -> Part -> Drawing -> CNC.Program), geometry, cutting strategies and diagnostics. Angles are radians; useTolerance.Epsilonfor geometry comparisons.OpenNest.MathshadowsSystem.Math, so qualify the latter.OpenNest.Engine: whole-job API inJobs/, interactive proposals viaPlateFillService, fill strategies, best-fit pairs, packing, sequencing and rapid planning.INestingEngine.Solve(NestJob)returns stock IDs/poses; boundary adapters map drawings and materialize results.NestJobRunnervalidates its candidates before committing demand/stock accounting. Do not assume arbitrary plug-in output or interactive paths received that validation. Job identity is reference-based, not drawing-name-based.- Built-in whole-job engines live in
OpenNest.Engine/NestingEngines/<Name>/, named for the jobs they suit; see nesting engines. A change must beat that engine's current benchmark result with every layout valid. External plug-ins implementINestingEnginewith a public parameterless constructor and load fromEngines/beside the host; keep their projects out of this solution. OpenNest.IO: ACadSharp import/export and ZIP-based.nestpersistence; depends on Core only (an IO.Tests guard enforces it). Best fits persist only when callers passBestFitCacheStore.SharedasNestReader/NestWriter.BestFitStore. All DXF-to-Drawing conversion goes throughCadImporter:Import+BuildDrawingfor editable/reporting flows,ImportDrawingfor headless callers. Preserve source offsets, entity IDs, suppressed entities and bends. Bend repair is opt-in, requires explicit source units and may not alter cut geometry or unrelated marks.OpenNest: WinForms UI (Forms/,Controls/PlateView,Actions/).OpenNest.Dataholds cross-platform persistence; new-nest defaults live in%APPDATA%\OpenNest\defaults.json(in Database mode, the server's shared copy once it holds one). WinFormsProperties.Settingspersist to%APPDATA%\OpenNest\user-settings.jsonthroughAppDataSettingsProvider, never inside the Velopack install folder. Posts live inPosts/OpenNest.Posts.<Name>/and deploy to the desktop output'sPosts/directory. Desktop nest edits go throughBeginChange/RecordChange; see undo and redo.OpenNest.Desktop(net8.0): toolkit-neutral desktop logic shared by the WinForms app andOpenNest.Avalonia, the cross-platform desktop in progress. It must not reference WinForms/WindowsDesktop,System.Drawing.Commonor Avalonia (OpenNest.Desktop.Testsguards this, including transitive packages); put toolkit-specific rendering, dialogs and settings behind adapters in the front ends.OpenNest.Console,OpenNest.Mcp,OpenNest.Api: front ends;OpenNest.Benchmark: whole-job engine comparisons;OpenNest.Gpu: GPU evaluators;OpenNest.Training: ML data collection and the Python sketch-search prototype (sketch-search/README.md). Benchmark timing comparisons require--parallel 1; validate layouts and fulfillment, not just elapsed time.
Geometry and ownership safeguards
- Marks are not material: use
SpecialLayers.IsMaterialwhen deriving nesting/collision geometry; exclude rapid and scribe moves without removing them from display, cutting time or posts. - Engine/validator collision paths retain the hand-written
Collisionkernel; its GPU port is on hold. Material-overlap diagnostics use Clipper2 per pair for connected shared-material islands and interior markers; see material-overlap diagnostics. Polygon consumers useClipperBridge; directional-distance consumers retain native-arc offsets. Validation usesOffsetForValidationandNestTolerances.SpacingSlack, not conservative display/preparation padding; Auto Nest's layout check, the runner's candidate validation and the pre-post part-spacing review all find spacing candidates with Core'sSpacingOutlineand confirm them onNativeContours(the outline circumscribes arcs by more than the slack), so they agree;NestLayoutCheck.Clearsskips the confirmation and stays stricter for engine certification. Do not loosen tolerances to hide failures. FillLineargeometry caches are per public call, keyed byProgramreference identity; never share them across calls/threads.PartOverlapCheckeris per check; parts/programs must not mutate during its lifetime.FillScoreranks count, utilization, compactness; exact ties keep the current layout. Custom comparers remain authoritative. Preserve extents' negative/nonfinite-input fallback, pair preparation and adjusted-column overlap checks. Do not remove bounds recomputations without threshold/rounding characterization.ObservableListevents own drawing/plate quantity tracking; avoid double accounting. Cutoff parts are excluded from quantity, utilization and overlap checks.- Cutoffs persist as definitions on
Plate.CutOffs; apply throughRegenerateCutOffs, never preview parts. Preserve sequence positions. Batch planning must finish before mutation and roll back on failure. UsePlateSequencing.Applyfor automatic cutoff dependencies, with nominal spans/reference identity rather than trimmed geometry/names. - A cutoff starts only at the origin-side edge: stock can be oversize, so the far edge is unknown. Only a head-locked overcut (
CutOff.HeadLockOvercut,HeadHeightLockmarkers) may start its far-edge segment there; posts refuse it without lock codes. - Fixed emissions (locked programs, drawing-pinned contours) are accepted as given: their violations warn on an UNVERIFIED proposal and never steer the search, while every planner-chosen motion stays strict. Plates without them must keep the
PlanningCharacterizationTestsdigests. - An empty diagnostic is not a clear result unless
IsComplete. Posting must run checks before writing CNC output; warnings require explicit per-attempt consent, never a persisted bypass. Keep inputs stable through analysis/cancellation. - Preserve symbolic G-code variable definitions/references in file round trips. Keep training bitmaps by default; inference checks predictor availability before scalar-only extraction.
Read the relevant contract before changing its behavior:
- Nest file format
- Directional slides and pair-spacing limits
- Lead-in placement (including the planner's eroded pierce for cutouts too small for their lead-in) and pierce zones: opt-in
PierceDiameterclearance, the hole pole fallback and the planner's perimeter scrap fallback - Breakoffs: tabbed scrap;
Break-layer open cuts that are cut but are not material - Tabbed cutouts: holes cut in pieces around
Tab-layer spans that are material but never cut; nesting reads material throughNestingMaterial.ForNesting, so nothing nests in them - Support tabs: the nest's support grid, the center-of-gravity check, and Plan Cutting's tab placement for parts the grid cannot hold level
- Material-overlap diagnostics
- Automatic cutoffs and sequencing
- Pre-post verification
- Machine cutting defaults: the nest's machine supplies leads, kerf and cut-off settings for plates without their own parameters
- Shared settings: in Database mode machines, post settings, clamps and nest defaults come from the server once it holds them; offline uses the last copy read, read-only
- Cut-time estimates: simulator/Calculate Cut Time acceleration planner and placeholder machine limits
- Cincinnati CL and CI Fiber
- Fill verification: opt-in benchmarks, frozen oracles, Debug-only counters and predictor initialization. Zero Release counters do not prove work removal.
- Desktop auto-update: GitHub Releases by default, opt-in rolling
dev-buildpre-release from green master pushes,UpdateFeedUrlfor a self-hosted feed, release Velopack assets andDeploy-OpenNest.ps1. - Undo and Redo: whole-nest history, the recording rule, what a restore rebuilds and what is excluded.
- Desktop help: WebView2 help window, F1 topic IDs and the pinned help release both packaging scripts install.