refactor(engine): expose the layout validation contract to engines
Engines had to reverse-engineer the benchmark validator: Opus55 assumed a 0.01 arc tolerance (the validator uses 0.001), Gpt6Astra added hand-tuned paddings and copied the validator's check order, Qwen picked its chord tolerance to stay under a constant it could not reference. NestTolerances publishes the validator's arc tolerance, the Clipper grid and SafeClearanceMargin (with its derivation). NestLayoutCheck moves the benchmark NestValidator's checks into OpenNest.Engine as a public API (Clears for a part pair, Violations for a whole result); NestValidator is now a thin wrapper. Verdicts are unchanged: tests compare ordered violation lists against a frozen copy of the old validator, and a tangent-disc stress test covers 432 pairs at the safe margin. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Engine.Jobs;
|
||||
|
||||
/// <summary>Shared numerical contract for layout validation.</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>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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user