feat: add IFillComparer hooks to NestEngineBase

Add virtual comparer, direction, and angle-building hooks to NestEngineBase
so subclasses can override scoring and direction policy. Rewire IsBetterFill
to delegate to the comparer instead of calling FillScore directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 12:43:45 -04:00
parent 4586a53590
commit 99546e7eef

View File

@@ -1,4 +1,6 @@
using OpenNest.Engine;
using OpenNest.Engine.Fill;
using OpenNest.Engine.Strategies;
using OpenNest.Geometry;
using System;
using System.Collections.Generic;
@@ -31,6 +33,25 @@ namespace OpenNest
public abstract string Description { get; }
// --- Engine policy ---
private IFillComparer _comparer;
protected IFillComparer Comparer => _comparer ??= CreateComparer();
protected virtual IFillComparer CreateComparer() => new DefaultFillComparer();
public virtual NestDirection? PreferredDirection => null;
public virtual List<double> BuildAngles(NestItem item, double bestRotation, Box workArea)
{
return new List<double> { bestRotation, bestRotation + OpenNest.Math.Angle.HalfPI };
}
protected virtual void RecordProductiveAngles(List<AngleResult> angleResults) { }
protected FillPolicy BuildPolicy() => new FillPolicy(Comparer, PreferredDirection);
// --- Virtual methods (side-effect-free, return parts) ---
public virtual List<Part> Fill(NestItem item, Box workArea,
@@ -255,15 +276,7 @@ namespace OpenNest
}
protected bool IsBetterFill(List<Part> candidate, List<Part> current, Box workArea)
{
if (candidate == null || candidate.Count == 0)
return false;
if (current == null || current.Count == 0)
return true;
return FillScore.Compute(candidate, workArea) > FillScore.Compute(current, workArea);
}
=> Comparer.IsBetter(candidate, current, workArea);
protected bool IsBetterValidFill(List<Part> candidate, List<Part> current, Box workArea)
{