mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 13:51:06 -04:00
Clamps could only sit on the origin-side edge and be edited as a list in Nest > Clamps. Setting them up against a real sheet is easier by dragging them where they are, so Plate > Edit Clamps adds an edit mode: drag a clamp along its edge or onto another edge, click near an edge to add one, click a clamp's locating dimension to type its distance from the origin, Delete to remove. Dimensions measure to the clamp center or its near edge (remembered per user). Edits replace the nest's rail so every sheet follows, like the dialog. Rail clamps now carry a ClampEdge (origin side, far side, origin end, far end), positioned from the origin along that edge. Origin-side clamps keep their ids and files; other edges persist in optional per-edge arrays in .nest files and clamps.json, omitted when empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
89 lines
3.0 KiB
C#
89 lines
3.0 KiB
C#
using System.IO.Compression;
|
|
using System.Text;
|
|
using System.Text.Json.Nodes;
|
|
using OpenNest.Geometry;
|
|
|
|
namespace OpenNest.IO.Tests;
|
|
|
|
/// <summary>
|
|
/// Rails with clamps on other edges than the origin side persist those clamps in optional
|
|
/// per-edge arrays; origin-side-only rails write exactly the keys they always did.
|
|
/// </summary>
|
|
public class ClampEdgePersistenceTests
|
|
{
|
|
private static ClampRail Mixed() => new(1.5, 0.625, new[]
|
|
{
|
|
new RailClamp(ClampEdge.OriginSide, 6),
|
|
new RailClamp(ClampEdge.FarSide, 20),
|
|
new RailClamp(ClampEdge.OriginEnd, 8),
|
|
new RailClamp(ClampEdge.FarEnd, 30),
|
|
});
|
|
|
|
private static Nest NestWith(ClampRail rail)
|
|
{
|
|
var nest = new Nest("edges");
|
|
nest.PlateDefaults.Size = new Size(48, 96);
|
|
nest.SetClampRail(rail);
|
|
var plate = nest.CreatePlate();
|
|
plate.CutOffs.Add(new CutOff(new Vector(40, 0), CutOffAxis.Vertical));
|
|
return nest;
|
|
}
|
|
|
|
private static MemoryStream Write(Nest nest)
|
|
{
|
|
var stream = new MemoryStream();
|
|
Assert.True(new NestWriter(nest).Write(stream));
|
|
stream.Position = 0;
|
|
return stream;
|
|
}
|
|
|
|
private static JsonNode RailJson(MemoryStream zip)
|
|
{
|
|
zip.Position = 0;
|
|
using var archive = new ZipArchive(zip, ZipArchiveMode.Read, leaveOpen: true);
|
|
using var reader = new StreamReader(archive.GetEntry("nest.json")!.Open(), Encoding.UTF8);
|
|
var json = JsonNode.Parse(reader.ReadToEnd())!["plateDefaults"]!["clampRail"]!;
|
|
zip.Position = 0;
|
|
return json;
|
|
}
|
|
|
|
[Fact]
|
|
public void ClampsOnEveryEdgeRoundTripAndPlatesFollowTheRail()
|
|
{
|
|
var reopened = new NestReader(Write(NestWith(Mixed()))).Read();
|
|
|
|
Assert.Equal(Mixed(), reopened.PlateDefaults.ClampRail);
|
|
var plate = Assert.Single(reopened.Plates);
|
|
Assert.Same(reopened.PlateDefaults.ClampRail, plate.ClampRail);
|
|
Assert.Equal(4, plate.ClampZones.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void OriginSideOnlyRailsOmitTheOtherEdgeKeys()
|
|
{
|
|
var rail = RailJson(Write(NestWith(new ClampRail(1.5, 0.625, new double[] { 6, 21 })))).AsObject();
|
|
|
|
Assert.Equal(new[] { "width", "depth", "centers", "removalMinutes" }, rail.Select(p => p.Key));
|
|
}
|
|
|
|
[Fact]
|
|
public void OtherEdgesAreWrittenInTheirOwnArrays()
|
|
{
|
|
var rail = RailJson(Write(NestWith(Mixed())));
|
|
|
|
Assert.Equal(6, rail["centers"]![0]!.GetValue<double>());
|
|
Assert.Equal(20, rail["farSideCenters"]![0]!.GetValue<double>());
|
|
Assert.Equal(8, rail["originEndCenters"]![0]!.GetValue<double>());
|
|
Assert.Equal(30, rail["farEndCenters"]![0]!.GetValue<double>());
|
|
}
|
|
|
|
[Fact]
|
|
public void ARailWithNoOriginSideClampsStillLoads()
|
|
{
|
|
var farOnly = new ClampRail(1.5, 0.625, new[] { new RailClamp(ClampEdge.FarSide, 12) });
|
|
var reopened = new NestReader(Write(NestWith(farOnly))).Read();
|
|
|
|
Assert.Equal(farOnly, reopened.PlateDefaults.ClampRail);
|
|
}
|
|
}
|