fix(ui): center parts within the plate work area

Center Parts centred the parts on the whole plate, ignoring edge
spacing, so a wider clamp-side margin left the parts closer to the
clamps than the opposite edge. It now centres them in Plate.WorkArea()
via the new Plate.OffsetToCenterPartsInWorkArea, so each side keeps
the same extra room beyond its edge spacing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ajandClaude Opus 5.5 committed 2026-10-17 22:09:07 -04:00
1 parent 3541249441
commit 7a1a554804
3 files changed
+59 -4

No files matched your search

+8
View File
@@ -710,6 +710,14 @@ namespace OpenNest
return box;
}
/// <summary>
/// The offset that centers the parts' combined bounds in the <see cref="WorkArea"/>,
/// so uneven edge spacing (such as a wider clamp-side margin) shifts them with it.
/// Zero when the plate has no parts.
/// </summary>
public Vector OffsetToCenterPartsInWorkArea() =>
Parts.Count == 0 ? new Vector() : WorkArea().Center - Parts.GetBoundingBox().Center;
/// <summary>
/// Automatically sizes the plate to fit the parts.
/// </summary>
+50
View File
@@ -0,0 +1,50 @@
using OpenNest.CNC;
using OpenNest.Geometry;
namespace OpenNest.Tests;
public class PlateCenterPartsTests
{
private static Part MakeSquare(Vector location)
{
var pgm = new Program();
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
pgm.Codes.Add(new LinearMove(new Vector(10, 0)));
pgm.Codes.Add(new LinearMove(new Vector(10, 10)));
pgm.Codes.Add(new LinearMove(new Vector(0, 10)));
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
return new Part(new Drawing("square", pgm), location);
}
[Fact]
public void CentersPartsInWorkAreaNotPlate()
{
var plate = new Plate(100, 100)
{
// Wider clamp-side margin at the bottom.
EdgeSpacing = new Spacing(left: 0.25, bottom: 0.75, right: 0.25, top: 0.25),
};
var part = MakeSquare(new Vector(5, 5));
plate.Parts.Add(part);
part.Offset(plate.OffsetToCenterPartsInWorkArea());
var box = part.BoundingBox;
// Work area is X 0.25..99.75, Y 0.75..99.75, so the centre sits 0.25 above the plate's.
Assert.Equal(50, box.Center.X, 6);
Assert.Equal(50.25, box.Center.Y, 6);
Assert.Equal(box.Left - 0.25, 99.75 - box.Right, 6);
Assert.Equal(box.Bottom - 0.75, 99.75 - box.Top, 6);
}
[Fact]
public void EmptyPlateNeedsNoOffset()
{
var plate = new Plate(100, 100) { EdgeSpacing = new Spacing(0.25, 0.75, 0.25, 0.25) };
var offset = plate.OffsetToCenterPartsInWorkArea();
Assert.Equal(0, offset.X);
Assert.Equal(0, offset.Y);
}
}
+1 -4
View File
@@ -229,10 +229,7 @@ namespace OpenNest.Forms
if (view?.Plate == null || view.Parts.Count == 0)
return;
var plateCenter = view.Plate.BoundingBox(false).Center;
var partsCenter = view.Parts.GetBoundingBox().Center;
var offset = plateCenter - partsCenter;
var offset = view.Plate.OffsetToCenterPartsInWorkArea();
foreach (var part in view.Parts)
part.Offset(offset);