From 8e46ed11759293a69763ffe921c5be40b11492e9 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sat, 14 Mar 2026 20:22:38 -0400 Subject: [PATCH] feat(engine): pass per-angle results through BruteForceResult Co-Authored-By: Claude Sonnet 4.6 --- OpenNest.Engine/ML/BruteForceRunner.cs | 28 +++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/OpenNest.Engine/ML/BruteForceRunner.cs b/OpenNest.Engine/ML/BruteForceRunner.cs index c3d8c59..efaa6e8 100644 --- a/OpenNest.Engine/ML/BruteForceRunner.cs +++ b/OpenNest.Engine/ML/BruteForceRunner.cs @@ -12,6 +12,15 @@ namespace OpenNest.Engine.ML public long TimeMs { get; set; } public string LayoutData { get; set; } public List PlacedParts { get; set; } + public string WinnerEngine { get; set; } = ""; + public long WinnerTimeMs { get; set; } + public string RunnerUpEngine { get; set; } = ""; + public int RunnerUpPartCount { get; set; } + public long RunnerUpTimeMs { get; set; } + public string ThirdPlaceEngine { get; set; } = ""; + public int ThirdPlacePartCount { get; set; } + public long ThirdPlaceTimeMs { get; set; } + public List AngleResults { get; set; } = new(); } public static class BruteForceRunner @@ -28,13 +37,30 @@ namespace OpenNest.Engine.ML if (parts == null || parts.Count == 0) return null; + // Rank phase results — winner is explicit, runners-up sorted by count. + var winner = engine.PhaseResults + .FirstOrDefault(r => r.Phase == engine.WinnerPhase); + var runnerUps = engine.PhaseResults + .Where(r => r.PartCount > 0 && r.Phase != engine.WinnerPhase) + .OrderByDescending(r => r.PartCount) + .ToList(); + return new BruteForceResult { PartCount = parts.Count, Utilization = CalculateUtilization(parts, plate.Area()), TimeMs = sw.ElapsedMilliseconds, LayoutData = SerializeLayout(parts), - PlacedParts = parts + PlacedParts = parts, + WinnerEngine = engine.WinnerPhase.ToString(), + WinnerTimeMs = winner?.TimeMs ?? 0, + RunnerUpEngine = runnerUps.Count > 0 ? runnerUps[0].Phase.ToString() : "", + RunnerUpPartCount = runnerUps.Count > 0 ? runnerUps[0].PartCount : 0, + RunnerUpTimeMs = runnerUps.Count > 0 ? runnerUps[0].TimeMs : 0, + ThirdPlaceEngine = runnerUps.Count > 1 ? runnerUps[1].Phase.ToString() : "", + ThirdPlacePartCount = runnerUps.Count > 1 ? runnerUps[1].PartCount : 0, + ThirdPlaceTimeMs = runnerUps.Count > 1 ? runnerUps[1].TimeMs : 0, + AngleResults = engine.AngleResults.ToList() }; }