refactor: extract training data collection into OpenNest.Training
Move brute-force data collection, TrainingDatabase, and GPU init from OpenNest.Console into a dedicated OpenNest.Training project. Replaces raw Microsoft.Data.Sqlite with EF Core. Console is now a pure nesting CLI with template support and cleaned-up usage output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
131
OpenNest.Training/TrainingDatabase.cs
Normal file
131
OpenNest.Training/TrainingDatabase.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OpenNest.Engine.ML;
|
||||
using OpenNest.IO;
|
||||
using OpenNest.Training.Data;
|
||||
|
||||
namespace OpenNest.Training
|
||||
{
|
||||
public class TrainingDatabase : IDisposable
|
||||
{
|
||||
private readonly TrainingDbContext _db;
|
||||
|
||||
public TrainingDatabase(string dbPath)
|
||||
{
|
||||
if (!dbPath.EndsWith(".db", StringComparison.OrdinalIgnoreCase))
|
||||
dbPath += ".db";
|
||||
|
||||
_db = new TrainingDbContext(dbPath);
|
||||
_db.Database.EnsureCreated();
|
||||
}
|
||||
|
||||
public long GetOrAddPart(string fileName, PartFeatures features, string geometryData)
|
||||
{
|
||||
var existing = _db.Parts.FirstOrDefault(p => p.FileName == fileName);
|
||||
if (existing != null) return existing.Id;
|
||||
|
||||
var part = new TrainingPart
|
||||
{
|
||||
FileName = fileName,
|
||||
Area = features.Area,
|
||||
Convexity = features.Convexity,
|
||||
AspectRatio = features.AspectRatio,
|
||||
BBFill = features.BoundingBoxFill,
|
||||
Circularity = features.Circularity,
|
||||
PerimeterToAreaRatio = features.PerimeterToAreaRatio,
|
||||
VertexCount = features.VertexCount,
|
||||
Bitmask = features.Bitmask,
|
||||
GeometryData = geometryData
|
||||
};
|
||||
|
||||
_db.Parts.Add(part);
|
||||
_db.SaveChanges();
|
||||
return part.Id;
|
||||
}
|
||||
|
||||
public bool HasRun(string fileName, double sheetWidth, double sheetHeight, double spacing)
|
||||
{
|
||||
return _db.Runs.Any(r =>
|
||||
r.Part.FileName == fileName &&
|
||||
r.SheetWidth == sheetWidth &&
|
||||
r.SheetHeight == sheetHeight &&
|
||||
r.Spacing == spacing);
|
||||
}
|
||||
|
||||
public int RunCount(string fileName)
|
||||
{
|
||||
return _db.Runs.Count(r => r.Part.FileName == fileName);
|
||||
}
|
||||
|
||||
public void AddRun(long partId, double w, double h, double s, BruteForceResult result, string filePath)
|
||||
{
|
||||
var run = new TrainingRun
|
||||
{
|
||||
PartId = partId,
|
||||
SheetWidth = w,
|
||||
SheetHeight = h,
|
||||
Spacing = s,
|
||||
PartCount = result.PartCount,
|
||||
Utilization = result.Utilization,
|
||||
TimeMs = result.TimeMs,
|
||||
LayoutData = result.LayoutData ?? "",
|
||||
FilePath = filePath ?? ""
|
||||
};
|
||||
|
||||
_db.Runs.Add(run);
|
||||
_db.SaveChanges();
|
||||
}
|
||||
|
||||
public int BackfillPerimeterToAreaRatio()
|
||||
{
|
||||
var partsToFix = _db.Parts
|
||||
.Where(p => p.PerimeterToAreaRatio == 0)
|
||||
.Select(p => new { p.Id, p.GeometryData })
|
||||
.ToList();
|
||||
|
||||
if (partsToFix.Count == 0) return 0;
|
||||
|
||||
var updated = 0;
|
||||
foreach (var item in partsToFix)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stream = new MemoryStream(Encoding.UTF8.GetBytes(item.GeometryData));
|
||||
var programReader = new ProgramReader(stream);
|
||||
var program = programReader.Read();
|
||||
|
||||
var drawing = new Drawing("backfill") { Program = program };
|
||||
drawing.UpdateArea();
|
||||
|
||||
var features = FeatureExtractor.Extract(drawing);
|
||||
if (features == null) continue;
|
||||
|
||||
var part = _db.Parts.Find(item.Id);
|
||||
part.PerimeterToAreaRatio = features.PerimeterToAreaRatio;
|
||||
_db.SaveChanges();
|
||||
updated++;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Skip parts that fail to reconstruct.
|
||||
}
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
public void SaveChanges()
|
||||
{
|
||||
_db.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_db?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user