feat: add plate creation and upgrade-vs-new evaluation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenNest.Engine.Fill;
|
||||
using OpenNest.Geometry;
|
||||
using OpenNest.Math;
|
||||
|
||||
namespace OpenNest
|
||||
{
|
||||
@@ -92,5 +93,76 @@ namespace OpenNest
|
||||
|
||||
return viable;
|
||||
}
|
||||
|
||||
public struct UpgradeDecision
|
||||
{
|
||||
public bool ShouldUpgrade;
|
||||
public double UpgradeCost;
|
||||
public double NewPlateCost;
|
||||
}
|
||||
|
||||
public static Plate CreatePlate(Plate template, List<PlateOption> options, Box minBounds)
|
||||
{
|
||||
var plate = new Plate(template.Size)
|
||||
{
|
||||
PartSpacing = template.PartSpacing,
|
||||
Quadrant = template.Quadrant,
|
||||
};
|
||||
plate.EdgeSpacing = new Spacing
|
||||
{
|
||||
Left = template.EdgeSpacing.Left,
|
||||
Right = template.EdgeSpacing.Right,
|
||||
Top = template.EdgeSpacing.Top,
|
||||
Bottom = template.EdgeSpacing.Bottom,
|
||||
};
|
||||
|
||||
if (options == null || options.Count == 0 || minBounds == null)
|
||||
return plate;
|
||||
|
||||
// Find smallest option that fits the part (by cost ascending).
|
||||
var sorted = options.OrderBy(o => o.Cost).ToList();
|
||||
|
||||
foreach (var option in sorted)
|
||||
{
|
||||
var workW = option.Width - template.EdgeSpacing.Left - template.EdgeSpacing.Right;
|
||||
var workL = option.Length - template.EdgeSpacing.Top - template.EdgeSpacing.Bottom;
|
||||
|
||||
var fitsNormal = workW >= minBounds.Width - Tolerance.Epsilon
|
||||
&& workL >= minBounds.Length - Tolerance.Epsilon;
|
||||
var fitsRotated = workW >= minBounds.Length - Tolerance.Epsilon
|
||||
&& workL >= minBounds.Width - Tolerance.Epsilon;
|
||||
|
||||
if (fitsNormal || fitsRotated)
|
||||
{
|
||||
plate.Size = new Size(option.Width, option.Length);
|
||||
return plate;
|
||||
}
|
||||
}
|
||||
|
||||
// No option fits — use template size.
|
||||
return plate;
|
||||
}
|
||||
|
||||
public static UpgradeDecision EvaluateUpgradeVsNew(
|
||||
PlateOption currentSize,
|
||||
PlateOption upgradeSize,
|
||||
PlateOption newPlateSize,
|
||||
double salvageRate,
|
||||
double estimatedNewPlateUtilization)
|
||||
{
|
||||
var upgradeCost = upgradeSize.Cost - currentSize.Cost;
|
||||
|
||||
var newPlateCost = newPlateSize.Cost;
|
||||
var remnantFraction = 1.0 - estimatedNewPlateUtilization;
|
||||
var salvageCredit = remnantFraction * newPlateSize.Cost * salvageRate;
|
||||
var netNewCost = newPlateCost - salvageCredit;
|
||||
|
||||
return new UpgradeDecision
|
||||
{
|
||||
ShouldUpgrade = upgradeCost < netNewCost,
|
||||
UpgradeCost = upgradeCost,
|
||||
NewPlateCost = netNewCost,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user