feat: wire FillPolicy into DefaultNestEngine and FillContext
- FillContext gains a Policy property (init-only) carrying the IFillComparer - DefaultNestEngine.Fill sets Policy = BuildPolicy() on every context - RunPipeline now uses context.Policy.Comparer.IsBetter instead of IsBetterFill - RunPipeline promoted to protected virtual so subclasses can override - BuildAngles/RecordProductiveAngles overrides delegate to angleBuilder - RunPipeline calls virtual BuildAngles/RecordProductiveAngles instead of angleBuilder directly - TODO comment added in group-fill overload for Task 6 Comparer pass-through Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,16 @@ namespace OpenNest
|
|||||||
set => angleBuilder.ForceFullSweep = value;
|
set => angleBuilder.ForceFullSweep = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override List<double> BuildAngles(NestItem item, double bestRotation, Box workArea)
|
||||||
|
{
|
||||||
|
return angleBuilder.Build(item, bestRotation, workArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void RecordProductiveAngles(List<AngleResult> angleResults)
|
||||||
|
{
|
||||||
|
angleBuilder.RecordProductive(angleResults);
|
||||||
|
}
|
||||||
|
|
||||||
// --- Public Fill API ---
|
// --- Public Fill API ---
|
||||||
|
|
||||||
public override List<Part> Fill(NestItem item, Box workArea,
|
public override List<Part> Fill(NestItem item, Box workArea,
|
||||||
@@ -42,6 +52,7 @@ namespace OpenNest
|
|||||||
PlateNumber = PlateNumber,
|
PlateNumber = PlateNumber,
|
||||||
Token = token,
|
Token = token,
|
||||||
Progress = progress,
|
Progress = progress,
|
||||||
|
Policy = BuildPolicy(),
|
||||||
};
|
};
|
||||||
|
|
||||||
RunPipeline(context);
|
RunPipeline(context);
|
||||||
@@ -78,6 +89,7 @@ namespace OpenNest
|
|||||||
PhaseResults.Clear();
|
PhaseResults.Clear();
|
||||||
var engine = new FillLinear(workArea, Plate.PartSpacing);
|
var engine = new FillLinear(workArea, Plate.PartSpacing);
|
||||||
var angles = RotationAnalysis.FindHullEdgeAngles(groupParts);
|
var angles = RotationAnalysis.FindHullEdgeAngles(groupParts);
|
||||||
|
// TODO: pass Comparer to FillPattern (Task 6)
|
||||||
var best = FillHelpers.FillPattern(engine, groupParts, angles, workArea);
|
var best = FillHelpers.FillPattern(engine, groupParts, angles, workArea);
|
||||||
PhaseResults.Add(new PhaseResult(NestPhase.Linear, best?.Count ?? 0, 0));
|
PhaseResults.Add(new PhaseResult(NestPhase.Linear, best?.Count ?? 0, 0));
|
||||||
|
|
||||||
@@ -105,12 +117,12 @@ namespace OpenNest
|
|||||||
|
|
||||||
// --- RunPipeline: strategy-based orchestration ---
|
// --- RunPipeline: strategy-based orchestration ---
|
||||||
|
|
||||||
private void RunPipeline(FillContext context)
|
protected virtual void RunPipeline(FillContext context)
|
||||||
{
|
{
|
||||||
var bestRotation = RotationAnalysis.FindBestRotation(context.Item);
|
var bestRotation = RotationAnalysis.FindBestRotation(context.Item);
|
||||||
context.SharedState["BestRotation"] = bestRotation;
|
context.SharedState["BestRotation"] = bestRotation;
|
||||||
|
|
||||||
var angles = angleBuilder.Build(context.Item, bestRotation, context.WorkArea);
|
var angles = BuildAngles(context.Item, bestRotation, context.WorkArea);
|
||||||
context.SharedState["AngleCandidates"] = angles;
|
context.SharedState["AngleCandidates"] = angles;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -131,7 +143,7 @@ namespace OpenNest
|
|||||||
// during progress reporting.
|
// during progress reporting.
|
||||||
PhaseResults.Add(phaseResult);
|
PhaseResults.Add(phaseResult);
|
||||||
|
|
||||||
if (IsBetterFill(result, context.CurrentBest, context.WorkArea))
|
if (context.Policy.Comparer.IsBetter(result, context.CurrentBest, context.WorkArea))
|
||||||
{
|
{
|
||||||
context.CurrentBest = result;
|
context.CurrentBest = result;
|
||||||
context.CurrentBestScore = FillScore.Compute(result, context.WorkArea);
|
context.CurrentBestScore = FillScore.Compute(result, context.WorkArea);
|
||||||
@@ -151,7 +163,7 @@ namespace OpenNest
|
|||||||
Debug.WriteLine("[RunPipeline] Cancelled, returning current best");
|
Debug.WriteLine("[RunPipeline] Cancelled, returning current best");
|
||||||
}
|
}
|
||||||
|
|
||||||
angleBuilder.RecordProductive(context.AngleResults);
|
RecordProductiveAngles(context.AngleResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,10 @@ namespace OpenNest.Engine.Strategies
|
|||||||
public int PlateNumber { get; init; }
|
public int PlateNumber { get; init; }
|
||||||
public CancellationToken Token { get; init; }
|
public CancellationToken Token { get; init; }
|
||||||
public IProgress<NestProgress> Progress { get; init; }
|
public IProgress<NestProgress> Progress { get; init; }
|
||||||
|
public FillPolicy Policy { get; init; }
|
||||||
|
|
||||||
public List<Part> CurrentBest { get; set; }
|
public List<Part> CurrentBest { get; set; }
|
||||||
|
/// <summary>For progress reporting only; comparisons use Policy.Comparer.</summary>
|
||||||
public FillScore CurrentBestScore { get; set; }
|
public FillScore CurrentBestScore { get; set; }
|
||||||
public NestPhase WinnerPhase { get; set; }
|
public NestPhase WinnerPhase { get; set; }
|
||||||
public List<PhaseResult> PhaseResults { get; } = new();
|
public List<PhaseResult> PhaseResults { get; } = new();
|
||||||
|
|||||||
Reference in New Issue
Block a user