Plugin engines (Opus55, Qwen, Terra) each add two projects at the repo root, and more are coming; at a dozen they would outnumber the core projects. They are also a different kind of thing: out-of-solution, runtime-loaded plugins. Grouping them under Engines/ keeps the root readable. Engines/Directory.Build.props now holds the shared TFM, nullable and implicit-usings settings and the OpenNest.Engine reference, so a new engine's csproj is nearly empty. The tests/ compile exclusion lives in Directory.Build.targets because a removal in .props runs before the SDK adds its default Compile glob and has no effect. Build-Engines.ps1 replaces the per-README manual build-and-copy steps for deploying engines into the benchmark's runtime Engines/ folder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
42 lines
1.6 KiB
C#
42 lines
1.6 KiB
C#
using OpenNest.Engine.Jobs;
|
|
|
|
namespace OpenNest.Engine.Opus55;
|
|
|
|
/// <summary>
|
|
/// The objective the engine optimizes: sheet area consumed, less the salvage credit for the
|
|
/// single largest full-width or full-length edge offcut the job's options allow. Packing toward
|
|
/// one edge (see <see cref="PackAxis"/>) is what makes that offcut large.
|
|
/// </summary>
|
|
internal static class SheetEconomics
|
|
{
|
|
public static double SheetArea(NestPlateStock stock) => stock.Size.Width * stock.Size.Length;
|
|
|
|
public static double NetArea(NestJobOptions options, SheetFill fill)
|
|
{
|
|
var area = SheetArea(fill.Stock);
|
|
var minimum = options.MinimumSalvageDimension;
|
|
if (options.SalvageRate <= 0 || minimum <= 0 || fill.Parts.Count == 0)
|
|
return area;
|
|
|
|
var work = FrontierPacker.WorkArea(fill.Stock);
|
|
var gap = fill.Stock.PartSpacing;
|
|
var left = fill.Parts.Min(p => p.Left);
|
|
var right = fill.Parts.Max(p => p.Right);
|
|
var bottom = fill.Parts.Min(p => p.Bottom);
|
|
var top = fill.Parts.Max(p => p.Top);
|
|
var offcuts = new[]
|
|
{
|
|
// Box.Length is the X extent, Box.Width the Y extent.
|
|
(work.Length, bottom - work.Bottom - gap),
|
|
(work.Length, work.Top - top - gap),
|
|
(left - work.Left - gap, work.Width),
|
|
(work.Right - right - gap, work.Width),
|
|
};
|
|
var salvage = 0.0;
|
|
foreach (var (a, b) in offcuts)
|
|
if (a >= minimum && b >= minimum)
|
|
salvage = System.Math.Max(salvage, a * b);
|
|
return area - options.SalvageRate * salvage;
|
|
}
|
|
}
|