mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-04 12:32:15 -04:00
Parts drawn a few millionths over their sheet's work area (for example a 36.125006 panel on a 36.125 sheet with no edge spacing) pass NestLayoutCheck, which allows Tolerance.Epsilon of overhang, but the Rectangles engine refused them and left them unplaced. The engine now allows 90% of that slack: a box that exceeds the sheet by no more than the allowance packs as exactly the sheet's size, so it spans the axis and the overhang lands only past the edge. The check's bounds slack is named NestTolerances.WorkAreaSlack (same value, no behavior change) so the engine and the test layout assertion share it. Rectangle-lane benchmark (91 strict + 77 boxable jobs): every layout valid; 4 jobs that left panels unplaced now place them (strict complete 86 -> 88, boxable complete 74 -> 75, one more boxable job places 2 more parts); no other job changed.
44 lines
2.4 KiB
C#
44 lines
2.4 KiB
C#
using System;
|
|
using OpenNest.Geometry;
|
|
using OpenNest.Math;
|
|
|
|
namespace OpenNest.Engine.Jobs;
|
|
|
|
/// <summary>Shared numerical contract for layout validation.
|
|
/// Only material contours (SpecialLayers.IsMaterial) count for bounds, clearance and scoring.
|
|
/// Scribe/etch marks never affect these checks or salvage envelopes, even outside the sheet.</summary>
|
|
public static class NestTolerances
|
|
{
|
|
/// <summary>Arc chord tolerance used by both validators. The layout check circumscribes
|
|
/// perimeter arcs and inscribes cutouts; the placement validator uses inscribed arcs.</summary>
|
|
public const double ValidationOutline = 0.001;
|
|
|
|
/// <summary>How far under the part spacing a gap may fall and still pass both validators.
|
|
/// Layouts placed exactly at the spacing land up to ~1e-4 short once rotated, rounded
|
|
/// coordinates (e.g. PEP's 4-decimal exports) meet the Clipper grid; 0.0005 covers that
|
|
/// with margin and is far below anything a cutting machine can resolve.</summary>
|
|
public const double SpacingSlack = 0.0005;
|
|
|
|
/// <summary>How far material may extend past the work area and still pass the layout check's
|
|
/// bounds test. Matches the general geometry tolerance, so a part drawn a few millionths
|
|
/// larger than its sheet's work area (as exported dimensions often are) is still accepted.</summary>
|
|
public const double WorkAreaSlack = Tolerance.Epsilon;
|
|
|
|
/// <summary>Clipper decimal precision (a 1e-4 coordinate grid).</summary>
|
|
public const int ClipperPrecision = ClipperBridge.Precision;
|
|
|
|
/// <summary>Extra pair clearance for an engine whose outline error is bounded by t.
|
|
/// Each of two boundaries contributes ValidationOutline from validator flattening,
|
|
/// one Clipper grid unit from rounding, and t from engine flattening: therefore
|
|
/// 2 * ValidationOutline + 2 * 10^(-ClipperPrecision) + 2 * t.
|
|
/// This budget assumes valid material geometry and bounded chord error on both sides.</summary>
|
|
/// <exception cref="ArgumentOutOfRangeException">Tolerance is negative or non-finite.</exception>
|
|
public static double SafeClearanceMargin(double engineChordTolerance)
|
|
{
|
|
if (!double.IsFinite(engineChordTolerance) || engineChordTolerance < 0)
|
|
throw new ArgumentOutOfRangeException(nameof(engineChordTolerance));
|
|
return 2 * ValidationOutline + 2 * System.Math.Pow(10, -ClipperPrecision)
|
|
+ 2 * engineChordTolerance;
|
|
}
|
|
}
|