Archived
Nests every part as the axis-aligned box of its material at its minimum-area rotation and packs boxes with a maximal-rectangles free list (6 placement rules x global/ordered pick). Sheet choice uses the salvage-credited look-ahead cost. Curved extremes read the way the layout check sees them (circumscribed arcs on the Clipper grid), so discs, rings and obrounds stay valid at box contact; an 80-job sweep failed 16-50 jobs before that rule. Local 2026 production lanes (--min-salvage-dimension 12, --parallel 3): - 91 all-rectangular jobs: 91/91 valid, cost 333081 vs best general 332153 (Gpt6Astra, 89/91 valid), 5.9 s vs 13.7 s (Opus55) and 169.5 s (Gpt6Astra) - 77 box-filling (>= 90%) jobs: 77/77 valid, lowest total cost 641637
32 lines
1.6 KiB
C#
32 lines
1.6 KiB
C#
using OpenNest.Engine.Testing;
|
|
using static OpenNest.Engine.Testing.JobBuilder;
|
|
using static OpenNest.Engine.Testing.Shapes;
|
|
using OpenNest.Engine.Jobs;
|
|
namespace OpenNest.Engine.Rectangles.Tests;
|
|
/// <summary>
|
|
/// Curved extremes (discs, rings, obrounds) and sloped ones (triangles) must clear the layout check
|
|
/// at every spacing: the check circumscribes arcs, so box-touching copies are only valid when the
|
|
/// catalog reads their boxes the way the check does. Failed at 16-50 of these 80 jobs before that.
|
|
/// </summary>
|
|
public class CurvedExtremeSweepTests
|
|
{
|
|
[Fact]
|
|
public void CurvedAndSlopedPartsPassTheLayoutCheckAtEverySpacing()
|
|
{
|
|
var bad = new List<string>(); var n = 0;
|
|
foreach (var r in new[] { 0.37, 0.5, 0.731, 1.0, 1.23, 2.0, 3.3, 5.0, 7.77, 12.0 })
|
|
foreach (var sp in new[] { 0.0, 0.1, 0.25, 0.3125 })
|
|
foreach (var rot in new[] { false, true })
|
|
foreach (var ring in new[] { false, true })
|
|
{
|
|
var pol = rot ? RotationPolicy.Automatic : RotationPolicy.Fixed(0);
|
|
var job = Job(new[] { Part("d", ring ? Ring(2 * r, r) : Disc(r), 12, pol), Part("o", Obround(4 * r, 1.3 * r), 6, pol), Part("t", Triangle(3 * r, 2 * r), 4, pol) },
|
|
new[] { Stock("s", 12 * r + 5, 14 * r + 5, spacing: sp) });
|
|
var res = new RectanglesNestingEngine().Solve(job); n++;
|
|
var v = NestLayoutCheck.Violations(job, res);
|
|
if (v.Count > 0) bad.Add($"r={r} sp={sp} rot={rot} ring={ring}: {v[0]}");
|
|
}
|
|
Assert.True(bad.Count == 0, $"{bad.Count}/{n}\n" + string.Join("\n", bad));
|
|
}
|
|
}
|