mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-11 07:31:53 -05:00
fix(plate-view): recompute part labels after a drawing edit
A part's sequence-number label point was computed once from the drawing's program and cached forever. Editing a drawing in the converter replaces that program, sometimes in a different frame, so the labels of every placed copy stayed at the old frame's point and drifted off the parts. Keep the cached point only while the drawing program (and its rotation) is the one it came from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b329dd6c6b
commit
bffcd52db1
2 files changed
+50
-2
No files matched your search
@@ -57,6 +57,42 @@ public class LayoutPartViewCacheTests
|
||||
AssertMatchesFreshBuild(layout, view);
|
||||
}, TimeSpan.FromMinutes(1), "Layout part rebuild test timed out.");
|
||||
|
||||
[Fact]
|
||||
public void LabelFollowsAReplacedDrawingProgram() => StaTestThread.Run(() =>
|
||||
{
|
||||
// Editing a drawing replaces its program, possibly in another frame; the part's sequence
|
||||
// label must be found again in the new frame, not kept from the old program.
|
||||
var drawing = new Drawing("Door stop", LShape(Vector.Zero));
|
||||
var part = new Part(drawing, new Vector(5, 7));
|
||||
using var view = new PlateView(ColorSchemeRegistry.Get("Workshop"));
|
||||
view.Matrix = new Matrix(2, 0, 0, -2, 0, 0);
|
||||
var layout = LayoutPart.Create(part, view);
|
||||
var before = layout.LabelScreenPoint;
|
||||
|
||||
drawing.Program = LShape(new Vector(-10, -5));
|
||||
layout.IsDirty = true;
|
||||
layout.UpdateView(view);
|
||||
|
||||
var fresh = LayoutPart.Create(part, view);
|
||||
Assert.NotEqual(before, fresh.LabelScreenPoint);
|
||||
Assert.Equal(fresh.LabelScreenPoint.X, layout.LabelScreenPoint.X, 2);
|
||||
Assert.Equal(fresh.LabelScreenPoint.Y, layout.LabelScreenPoint.Y, 2);
|
||||
fresh.ReleaseDisplayResources();
|
||||
}, TimeSpan.FromMinutes(1), "Layout part label test timed out.");
|
||||
|
||||
private static Program LShape(Vector origin)
|
||||
{
|
||||
var program = new Program();
|
||||
program.MoveTo(origin.X, origin.Y);
|
||||
program.LineTo(origin.X + 10, origin.Y);
|
||||
program.LineTo(origin.X + 10, origin.Y + 30);
|
||||
program.LineTo(origin.X + 40, origin.Y + 30);
|
||||
program.LineTo(origin.X + 40, origin.Y + 40);
|
||||
program.LineTo(origin.X, origin.Y + 40);
|
||||
program.LineTo(origin.X, origin.Y);
|
||||
return program;
|
||||
}
|
||||
|
||||
private static void AssertMatchesFreshBuild(LayoutPart layout, PlateView view)
|
||||
{
|
||||
var fresh = LayoutPart.Create(layout.BasePart, view);
|
||||
|
||||
+14
-2
@@ -34,7 +34,11 @@ namespace OpenNest
|
||||
private double _cachedOffsetTolerance;
|
||||
private double _cachedOffsetRotation = double.NaN;
|
||||
|
||||
// The label point is in the frame of the drawing program it was computed from; editing a
|
||||
// drawing replaces that program, so the cache is kept only while the program is the same.
|
||||
private Vector? _labelPoint;
|
||||
private CNC.Program _labelProgram;
|
||||
private double _labelProgramRotation;
|
||||
private PointF _labelScreenPoint;
|
||||
|
||||
internal PointF LabelScreenPoint => _labelScreenPoint;
|
||||
@@ -456,8 +460,16 @@ namespace OpenNest
|
||||
|
||||
private Vector PlacedLabelPoint()
|
||||
{
|
||||
_labelPoint ??= ComputeLabelPoint();
|
||||
var baseRotation = BasePart.BaseDrawing.Program.Rotation;
|
||||
var drawingProgram = BasePart.BaseDrawing.Program;
|
||||
var baseRotation = drawingProgram.Rotation;
|
||||
if (_labelPoint == null
|
||||
|| !ReferenceEquals(_labelProgram, drawingProgram)
|
||||
|| _labelProgramRotation != baseRotation)
|
||||
{
|
||||
_labelPoint = ComputeLabelPoint();
|
||||
_labelProgram = drawingProgram;
|
||||
_labelProgramRotation = baseRotation;
|
||||
}
|
||||
return _labelPoint.Value.Rotate(BasePart.Rotation - baseRotation) + BasePart.Location;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user