Files
OpenNest/OpenNest.Engine/Jobs/NestTolerances.cs
T
ajandClaude Opus 5.5 07499fe1cd fix(engine): judge part spacing alike in the layout check and runner
NestLayoutCheck rejected Fill layouts whose interlocked arcs sat exactly
at the part spacing: its SpacingOutline circumscribes arcs by up to 0.001
each, more than the 0.0005 slack, so facing arcs overlapped. The runner's
placement validator measured inscribed 0.001 polygons instead and so
accepted gaps up to ~0.002 under the slack.

Both now find candidates with SpacingOutline and confirm them on
NativeContours, the native contours flattened at a twentieth of the slack
(moved out of PartSpacingReview, which keeps using them). The runner calls
NestLayoutCheck.KeepsSpacing, the same outline, tie rule and
confirmation, so the two validators accept exactly the same pairs.
Clears stays unconfirmed and stricter for engine certification. No
tolerance changed.

FixedStrategyEngine_IrregularJob pins now assert LayoutAssert.Valid with
unchanged digests; the NativeU 70-part grid's 28 reports were the same
cause and its test now requires none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 21:58:41 -04:00

43 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 of the spacing outline (perimeter arcs circumscribed,
/// cutouts inscribed) and of the placement validator's overlap check (arcs inscribed).
/// Spacing candidates the outline flags are confirmed on <see cref="NativeContours"/>.</summary>
public const double ValidationOutline = SpacingOutline.ChordTolerance;
/// <summary>How far under the part spacing a gap may fall and still pass both validators
/// and the pre-post spacing review; see <see cref="SpacingOutline.SpacingSlack"/>.</summary>
public const double SpacingSlack = SpacingOutline.SpacingSlack;
/// <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;
}
}