From d2eeb23107ba0003aca2635cffae28048bf4d00b Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Wed, 18 Mar 2026 07:26:04 -0400 Subject: [PATCH] refactor(io): migrate nest file extension from .zip to .opnest Add FileExtension and FileFilter constants to NestFormat and update all references across Console, MCP, Training, and WinForms projects. Co-Authored-By: Claude Opus 4.6 (1M context) --- OpenNest.Console/Program.cs | 21 ++++++++++++--------- OpenNest.IO/NestFormat.cs | 3 +++ OpenNest.Mcp/Tools/InputTools.cs | 4 ++-- OpenNest.Mcp/Tools/TestTools.cs | 4 ++-- OpenNest.Training/Program.cs | 4 ++-- OpenNest/Forms/EditNestForm.cs | 2 +- OpenNest/Forms/MainForm.cs | 2 +- 7 files changed, 23 insertions(+), 17 deletions(-) diff --git a/OpenNest.Console/Program.cs b/OpenNest.Console/Program.cs index 2997e1e..a4f750a 100644 --- a/OpenNest.Console/Program.cs +++ b/OpenNest.Console/Program.cs @@ -152,7 +152,8 @@ static class NestConsole static Nest LoadOrCreateNest(Options options) { var nestFile = options.InputFiles.FirstOrDefault(f => - f.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)); + f.EndsWith(NestFormat.FileExtension, StringComparison.OrdinalIgnoreCase) + || f.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)); var dxfFiles = options.InputFiles.Where(f => f.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase)).ToList(); @@ -190,7 +191,7 @@ static class NestConsole // DXF-only mode: create a fresh nest. if (dxfFiles.Count == 0) { - Console.Error.WriteLine("Error: no nest (.zip) or DXF (.dxf) files specified"); + Console.Error.WriteLine("Error: no nest (.opnest) or DXF (.dxf) files specified"); return null; } @@ -272,7 +273,9 @@ static class NestConsole plate.PartSpacing = options.Spacing.Value; // Only apply size override when it wasn't already used to create the plate. - var hasDxfOnly = !options.InputFiles.Any(f => f.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)); + var hasDxfOnly = !options.InputFiles.Any(f => + f.EndsWith(NestFormat.FileExtension, StringComparison.OrdinalIgnoreCase) + || f.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)); if (options.PlateSize.HasValue && !hasDxfOnly) plate.Size = options.PlateSize.Value; @@ -373,7 +376,7 @@ static class NestConsole var firstInput = options.InputFiles[0]; var outputFile = options.OutputFile ?? Path.Combine( Path.GetDirectoryName(firstInput), - $"{Path.GetFileNameWithoutExtension(firstInput)}-result.zip"); + $"{Path.GetFileNameWithoutExtension(firstInput)}-result{NestFormat.FileExtension}"); new NestWriter(nest).Write(outputFile); Console.WriteLine($"Saved: {outputFile}"); @@ -384,12 +387,12 @@ static class NestConsole Console.Error.WriteLine("Usage: OpenNest.Console [options]"); Console.Error.WriteLine(); Console.Error.WriteLine("Arguments:"); - Console.Error.WriteLine(" input-files One or more .zip nest files or .dxf drawing files"); + Console.Error.WriteLine(" input-files One or more .opnest nest files or .dxf drawing files"); Console.Error.WriteLine(); Console.Error.WriteLine("Modes:"); - Console.Error.WriteLine(" Load nest and fill (existing behavior)"); - Console.Error.WriteLine(" --size WxL Import DXF, create plate, and fill"); - Console.Error.WriteLine(" Load nest and add imported DXF drawings"); + Console.Error.WriteLine(" Load nest and fill (existing behavior)"); + Console.Error.WriteLine(" --size WxL Import DXF, create plate, and fill"); + Console.Error.WriteLine(" Load nest and add imported DXF drawings"); Console.Error.WriteLine(); Console.Error.WriteLine("Options:"); Console.Error.WriteLine(" --drawing Drawing name to fill with (default: first drawing)"); @@ -397,7 +400,7 @@ static class NestConsole Console.Error.WriteLine(" --quantity Max parts to place (default: 0 = unlimited)"); Console.Error.WriteLine(" --spacing Override part spacing"); Console.Error.WriteLine(" --size Override plate size (e.g. 60x120); required for DXF-only mode"); - Console.Error.WriteLine(" --output Output nest file path (default: -result.zip)"); + Console.Error.WriteLine(" --output Output nest file path (default: -result.opnest)"); Console.Error.WriteLine(" --template Nest template for plate defaults (thickness, quadrant, material, spacing)"); Console.Error.WriteLine(" --autonest Use NFP-based mixed-part autonesting instead of linear fill"); Console.Error.WriteLine(" --keep-parts Don't clear existing parts before filling"); diff --git a/OpenNest.IO/NestFormat.cs b/OpenNest.IO/NestFormat.cs index 60a0097..dd7e05d 100644 --- a/OpenNest.IO/NestFormat.cs +++ b/OpenNest.IO/NestFormat.cs @@ -5,6 +5,9 @@ namespace OpenNest.IO { public static class NestFormat { + public const string FileExtension = ".opnest"; + public const string FileFilter = "Nest Files (*.opnest)|*.opnest"; + public static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, diff --git a/OpenNest.Mcp/Tools/InputTools.cs b/OpenNest.Mcp/Tools/InputTools.cs index 8271f80..95c1329 100644 --- a/OpenNest.Mcp/Tools/InputTools.cs +++ b/OpenNest.Mcp/Tools/InputTools.cs @@ -21,8 +21,8 @@ namespace OpenNest.Mcp.Tools } [McpServerTool(Name = "load_nest")] - [Description("Load a .nest zip file into the session. Returns a summary of plates, parts, and drawings.")] - public string LoadNest([Description("Absolute path to the .nest file")] string path) + [Description("Load an .opnest file into the session. Returns a summary of plates, parts, and drawings.")] + public string LoadNest([Description("Absolute path to the .opnest file")] string path) { if (!File.Exists(path)) return $"Error: file not found: {path}"; diff --git a/OpenNest.Mcp/Tools/TestTools.cs b/OpenNest.Mcp/Tools/TestTools.cs index 971861b..afea628 100644 --- a/OpenNest.Mcp/Tools/TestTools.cs +++ b/OpenNest.Mcp/Tools/TestTools.cs @@ -17,10 +17,10 @@ namespace OpenNest.Mcp.Tools [McpServerTool(Name = "test_engine")] [Description("Build and run the nesting engine against a nest file. Returns fill results and a debug log file path for grepping. Use this to test engine changes without restarting the MCP server.")] public string TestEngine( - [Description("Path to the nest .zip file")] string nestFile = @"C:\Users\AJ\Desktop\4980 A24 PT02 60x120 45pcs v2.zip", + [Description("Path to the nest .opnest file")] string nestFile = @"C:\Users\AJ\Desktop\4980 A24 PT02 60x120 45pcs v2.opnest", [Description("Drawing name to fill with (default: first drawing)")] string drawingName = null, [Description("Plate index to fill (default: 0)")] int plateIndex = 0, - [Description("Output nest file path (default: -result.zip)")] string outputFile = null) + [Description("Output nest file path (default: -result.opnest)")] string outputFile = null) { if (!File.Exists(nestFile)) return $"Error: nest file not found: {nestFile}"; diff --git a/OpenNest.Training/Program.cs b/OpenNest.Training/Program.cs index 421e00c..eecc276 100644 --- a/OpenNest.Training/Program.cs +++ b/OpenNest.Training/Program.cs @@ -234,7 +234,7 @@ int RunDataCollection(string dir, string dbPath, string saveDir, double s, strin Directory.CreateDirectory(partDir); var nestName = $"{partNo}-{size.Length}x{size.Width}-{result.PartCount}pcs"; - var fileName = nestName + ".zip"; + var fileName = nestName + NestFormat.FileExtension; savedFilePath = Path.Combine(partDir, fileName); // Create nest from template or from scratch @@ -299,7 +299,7 @@ void PrintUsage() Console.Error.WriteLine("Options:"); Console.Error.WriteLine(" --spacing Part spacing (default: 0.5)"); Console.Error.WriteLine(" --db SQLite database path (default: OpenNestTraining.db)"); - Console.Error.WriteLine(" --save-nests Directory to save individual .zip nests for each winner"); + Console.Error.WriteLine(" --save-nests Directory to save individual .opnest nests for each winner"); Console.Error.WriteLine(" --template Nest template (.nstdot) for plate defaults"); Console.Error.WriteLine(" -h, --help Show this help"); } diff --git a/OpenNest/Forms/EditNestForm.cs b/OpenNest/Forms/EditNestForm.cs index 43f97b2..e85f678 100644 --- a/OpenNest/Forms/EditNestForm.cs +++ b/OpenNest/Forms/EditNestForm.cs @@ -288,7 +288,7 @@ namespace OpenNest.Forms public void SaveAs() { var dlg = new SaveFileDialog(); - dlg.Filter = "Nest Files|*.zip|Template File|*.nstdot"; + dlg.Filter = $"{NestFormat.FileFilter}|Template File|*.nstdot"; dlg.FileName = Nest.Name; if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) diff --git a/OpenNest/Forms/MainForm.cs b/OpenNest/Forms/MainForm.cs index da094f9..fa2f936 100644 --- a/OpenNest/Forms/MainForm.cs +++ b/OpenNest/Forms/MainForm.cs @@ -403,7 +403,7 @@ namespace OpenNest.Forms private void Open_Click(object sender, EventArgs e) { var dlg = new OpenFileDialog(); - dlg.Filter = "Nest Files (*.zip) | *.zip"; + dlg.Filter = NestFormat.FileFilter; dlg.Multiselect = true; if (dlg.ShowDialog() == DialogResult.OK)