using OpenNest.Geometry;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
namespace OpenNest.Benchmark
{
///
/// Runs every candidate engine against every job. Each (job, engine) pair gets
/// its own freshly-built Plate and NestItem list (via BenchmarkJob.CreatePlate/
/// CreateItems), so no engine can see another's mutated state and no job can
/// leak partial state into the next run of the same engine.
///
public static class BenchmarkRunner
{
public static List Run(List jobs, IReadOnlyList engines)
{
var results = new List(jobs.Count * engines.Count);
foreach (var job in jobs)
{
foreach (var engineInfo in engines)
{
results.Add(RunOne(job, engineInfo));
}
}
return results;
}
private static JobResult RunOne(BenchmarkJob job, NestEngineInfo engineInfo)
{
var plate = job.CreatePlate();
var items = job.CreateItems();
var requested = job.TotalRequestedQuantity;
var sw = Stopwatch.StartNew();
List parts;
try
{
var engine = engineInfo.Factory(plate);
parts = engine.Nest(items, null, CancellationToken.None) ?? new List();
}
catch (Exception ex)
{
sw.Stop();
return new JobResult
{
EngineName = engineInfo.Name,
JobName = job.Name,
Valid = false,
PartsRequested = requested,
ElapsedMs = sw.ElapsedMilliseconds,
Error = $"{ex.GetType().Name}: {ex.Message}",
};
}
sw.Stop();
var validation = NestValidator.Validate(parts, plate, job);
// Matches Plate.Utilization(): full sheet area, not just the cuttable
// work area, since that's what the material actually costs.
var plateArea = plate.Area();
var placedArea = validation.Valid ? parts.Sum(p => p.BaseDrawing.Area) : 0;
var usedBox = parts.Count > 0 ? parts.GetBoundingBox() : Box.Empty;
return new JobResult
{
EngineName = engineInfo.Name,
JobName = job.Name,
Valid = validation.Valid,
Violations = validation.Violations,
PartsPlaced = parts.Count,
PartsRequested = requested,
PlacedArea = placedArea,
PlateArea = plateArea,
UsedBoundingBoxArea = usedBox.Width * usedBox.Length,
ElapsedMs = sw.ElapsedMilliseconds,
};
}
}
}