mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-06 15:45:44 -05:00
Slice 3 of common-line cutting. On costly plate (N26-295: 3/16 RA310S at about $2,500 a sheet) pairing parts one kerf apart fits the part the spacing cannot: the last plate's 38 parts fit on one 48x120 with Auto Nest only with pairs. - Drawing Properties gains "Allow common line" (Drawing.AllowCommonLine, off by default because customer edge-quality needs vary). The nest's CommonLineUsage (Off / When it adds parts / Whenever available) is set in Auto Nest and seeded from Tools > Nest Defaults; both persist (nest.json, defaults.json). - NestPipeline runs the ordinary solve, then, with a level on, trials where eligible parts are offered as kerf-gap pair compounds. Placed pairs expand into parts plus explicit NestJobCommonLine groups, are validated again, and CommonLineRanking keeps a trial only by the level: count first, then sheets; "when it adds parts" keeps the plain layout on a tie, "whenever" also takes a shorter cut or less material, never at the cost of a part. Engines, FillScore and their comparers are unchanged; Off asks the engine exactly what it did. - NestLayoutCheck exempts members only through a sheet's explicit group list and only when the job allows common lines; materializing and committing create Plate.CommonLines. - Server nesting writes common-line jobs as version 3 and replays the recorded trial answers, so the desktop binds the same groups. - Fill Area honors the level through a PlateFillService overload. - The benchmark gains --common-lines <level> --kerf <k>. Benchmark (synthetic nests + N26-295, --parallel 1): with no flag and with --common-lines off every engine matches the base commit; with a level on no layout becomes invalid and three runs save a sheet at equal nested area. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
82 lines
3.2 KiB
C#
82 lines
3.2 KiB
C#
using System.Windows.Forms;
|
|
using OpenNest.Data;
|
|
using OpenNest.Forms;
|
|
using OpenNest.Geometry;
|
|
|
|
namespace OpenNest.WinForms.Tests.Forms;
|
|
|
|
public class NestDefaultsFormTests
|
|
{
|
|
[Fact]
|
|
public void SwitchingUnitsConvertsTheShownValues()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
var machine = new MachineConfig { Name = "Laser" };
|
|
var defaults = new NestDefaults
|
|
{
|
|
Units = Units.Inches,
|
|
Size = new Size(48, 96),
|
|
Quadrant = 3,
|
|
PartSpacing = 0.25,
|
|
EdgeSpacing = new Spacing(0.5, 1, 1.5, 2),
|
|
MachineId = machine.Id,
|
|
};
|
|
using var form = new NestDefaultsForm(defaults, new[] { machine }, ("Saved on this PC.", false));
|
|
Assert.Equal("in", Control<OpenNest.Controls.NumericUpDown>(form, "widthBox").Suffix);
|
|
|
|
Control<RadioButton>(form, "millimetersRadio").Checked = true;
|
|
|
|
var converted = form.GetDefaults();
|
|
Assert.Equal(Units.Millimeters, converted.Units);
|
|
Assert.Equal(new Size(1219.2, 2438.4), converted.Size);
|
|
Assert.Equal(6.35, converted.PartSpacing);
|
|
Assert.Equal(new Spacing(12.7, 25.4, 38.1, 50.8), converted.EdgeSpacing);
|
|
Assert.Equal(3, converted.Quadrant);
|
|
Assert.Equal(machine.Id, converted.MachineId);
|
|
Assert.Equal("mm", Control<OpenNest.Controls.NumericUpDown>(form, "edgeTopBox").Suffix);
|
|
|
|
Control<RadioButton>(form, "inchesRadio").Checked = true;
|
|
Assert.Equal(new Size(48, 96), form.GetDefaults().Size);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void ReadOnlySourceDisablesSave()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
using var form = new NestDefaultsForm(new NestDefaults(), Array.Empty<MachineConfig>(),
|
|
("Shared, read-only: the server cannot be reached.", true));
|
|
Assert.False(Control<Button>(form, "saveButton").Enabled);
|
|
Assert.Equal("Shared, read-only: the server cannot be reached.", Control<Label>(form, "sourceLabel").Text);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void CommonLineUsage_LoadsAndSaves_AndSurvivesAUnitSwitch()
|
|
{
|
|
RunSta(() =>
|
|
{
|
|
using var form = new NestDefaultsForm(new NestDefaults { CommonLineUsage = CommonLineUsage.Whenever },
|
|
Array.Empty<MachineConfig>(), ("Saved on this PC.", false));
|
|
var combo = Control<ComboBox>(form, "commonLineCombo");
|
|
Assert.Equal(2, combo.SelectedIndex);
|
|
|
|
Control<RadioButton>(form, "millimetersRadio").Checked = true;
|
|
Assert.Equal(CommonLineUsage.Whenever, form.GetDefaults().CommonLineUsage);
|
|
|
|
combo.SelectedIndex = 1;
|
|
Assert.Equal(CommonLineUsage.WhenItAddsParts, form.GetDefaults().CommonLineUsage);
|
|
combo.SelectedIndex = 0;
|
|
Assert.Equal(CommonLineUsage.Off, form.GetDefaults().CommonLineUsage);
|
|
});
|
|
}
|
|
|
|
private static T Control<T>(NestDefaultsForm form, string name) where T : Control =>
|
|
Assert.IsType<T>(form.Controls.Find(name, true).Single());
|
|
|
|
private static void RunSta(System.Action action) =>
|
|
StaTestThread.Run(action, Timeout.InfiniteTimeSpan, "The STA test did not complete.");
|
|
}
|