mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-17 19:41:40 -04:00
127 lines
5.7 KiB
C#
127 lines
5.7 KiB
C#
using System.Drawing;
|
|
using System.Reflection;
|
|
using OpenNest.Actions;
|
|
using OpenNest.CNC;
|
|
using OpenNest.Controls;
|
|
using OpenNest.Geometry;
|
|
|
|
namespace OpenNest.WinForms.Tests;
|
|
|
|
public class CutOffWindowSelectionTests
|
|
{
|
|
[Theory]
|
|
[InlineData(CutOffAxis.Vertical, 1)]
|
|
[InlineData(CutOffAxis.Horizontal, 2)]
|
|
[InlineData(CutOffAxis.Vertical, 3)]
|
|
[InlineData(CutOffAxis.Horizontal, 4)]
|
|
public void WindowSelectsVisibleCutOffSegmentsInBothDirections(CutOffAxis axis, int quadrant) => RunSta(() =>
|
|
{
|
|
var plate = new Plate(20, 20) { Quadrant = quadrant };
|
|
var bounds = plate.BoundingBox(includeParts: false);
|
|
var cutoff = new CutOff(bounds.Center, axis);
|
|
plate.CutOffs.Add(cutoff);
|
|
cutoff.Regenerate(plate, new CutOffSettings());
|
|
using var view = new PlateView { Plate = plate };
|
|
var full = GraphRect(view, new Vector(bounds.Left - 1, bounds.Bottom - 1),
|
|
new Vector(bounds.Right + 1, bounds.Top + 1));
|
|
var crossing = GraphRect(view, new Vector(bounds.Center.X - 1, bounds.Center.Y - 1),
|
|
new Vector(bounds.Center.X + 1, bounds.Center.Y + 1));
|
|
var missed = GraphRect(view, new Vector(bounds.Left + 1, bounds.Bottom + 1),
|
|
new Vector(bounds.Left + 2, bounds.Bottom + 2));
|
|
|
|
Assert.Contains(cutoff, view.Selection.GetCutOffsFromWindow(full, SelectionType.Contains));
|
|
Assert.Empty(view.Selection.GetCutOffsFromWindow(crossing, SelectionType.Contains));
|
|
Assert.Contains(cutoff, view.Selection.GetCutOffsFromWindow(crossing, SelectionType.Intersect));
|
|
Assert.Empty(view.Selection.GetCutOffsFromWindow(missed, SelectionType.Intersect));
|
|
});
|
|
|
|
[Fact]
|
|
public void WindowUsesActualSegmentsNotTheNominalLineOrGap() => RunSta(() =>
|
|
{
|
|
using var view = new PlateView();
|
|
var cutoff = new CutOff(new Vector(10, 10), CutOffAxis.Vertical);
|
|
view.Plate.CutOffs.Add(cutoff);
|
|
cutoff.Drawing.Program = new CNC.Program();
|
|
cutoff.Drawing.Program.Codes.Add(new RapidMove(new Vector(10, 0)));
|
|
cutoff.Drawing.Program.Codes.Add(new LinearMove(new Vector(10, 4)));
|
|
cutoff.Drawing.Program.Codes.Add(new RapidMove(new Vector(10, 16)));
|
|
cutoff.Drawing.Program.Codes.Add(new LinearMove(new Vector(10, 20)));
|
|
|
|
var gap = GraphRect(view, new Vector(9, 8), new Vector(11, 12));
|
|
var oneSegment = GraphRect(view, new Vector(9, -1), new Vector(11, 5));
|
|
var full = GraphRect(view, new Vector(9, -1), new Vector(11, 21));
|
|
Assert.Empty(view.Selection.GetCutOffsFromWindow(gap, SelectionType.Intersect));
|
|
Assert.Empty(view.Selection.GetCutOffsFromWindow(oneSegment, SelectionType.Contains));
|
|
Assert.Contains(cutoff, view.Selection.GetCutOffsFromWindow(oneSegment, SelectionType.Intersect));
|
|
Assert.Contains(cutoff, view.Selection.GetCutOffsFromWindow(full, SelectionType.Contains));
|
|
|
|
cutoff.Drawing.Program = new CNC.Program();
|
|
Assert.Empty(view.Selection.GetCutOffsFromWindow(full, SelectionType.Intersect));
|
|
Assert.Empty(view.Selection.GetCutOffsFromWindow(full, SelectionType.Contains));
|
|
});
|
|
|
|
[Fact]
|
|
public void ActionSelectsPartsAndCutOffsTogetherAndDeleteRemovesBoth() => RunSta(() =>
|
|
{
|
|
var plate = new Plate(20, 20);
|
|
var program = new CNC.Program();
|
|
program.MoveTo(2, 2);
|
|
program.LineTo(4, 2);
|
|
program.LineTo(4, 4);
|
|
program.LineTo(2, 4);
|
|
program.LineTo(2, 2);
|
|
plate.Parts.Add(new Part(new Drawing("square", program)));
|
|
var cutoff = new CutOff(new Vector(10, 10), CutOffAxis.Vertical);
|
|
plate.CutOffs.Add(cutoff);
|
|
cutoff.Regenerate(plate, new CutOffSettings());
|
|
using var view = new PlateView { Plate = plate };
|
|
var action = new ActionSelect(view);
|
|
try
|
|
{
|
|
action.Point1 = new Vector(0, 0);
|
|
action.Point2 = new Vector(20, 20); // left-to-right: contain
|
|
SelectWindow(action);
|
|
SelectWindow(action); // repeated selection must not duplicate a definition
|
|
Assert.Single(view.SelectedParts);
|
|
Assert.Same(cutoff, Assert.Single(view.Selection.SelectedCutOffs));
|
|
Assert.True(action.IsBusy());
|
|
|
|
view.Selection.DeleteSelected();
|
|
Assert.Empty(plate.CutOffs);
|
|
Assert.Empty(plate.Parts);
|
|
Assert.Empty(view.SelectedParts);
|
|
Assert.Empty(view.Selection.SelectedCutOffs);
|
|
|
|
plate.CutOffs.Add(cutoff);
|
|
cutoff.Regenerate(plate, view.CutOffSettings);
|
|
action.Point1 = new Vector(12, 12);
|
|
action.Point2 = new Vector(8, 8); // right-to-left: intersect
|
|
SelectWindow(action);
|
|
Assert.Same(cutoff, Assert.Single(view.Selection.SelectedCutOffs));
|
|
Assert.True(action.IsBusy());
|
|
action.CancelAction();
|
|
Assert.Empty(view.Selection.SelectedCutOffs);
|
|
Assert.False(action.IsBusy());
|
|
}
|
|
finally
|
|
{
|
|
action.DisconnectEvents();
|
|
}
|
|
});
|
|
|
|
private static void SelectWindow(ActionSelect action) =>
|
|
typeof(ActionSelect).GetMethod("SelectPartsInWindow", BindingFlags.Instance | BindingFlags.NonPublic)!
|
|
.Invoke(action, null);
|
|
|
|
private static RectangleF GraphRect(PlateView view, Vector first, Vector second)
|
|
{
|
|
var a = view.PointWorldToGraph(first);
|
|
var b = view.PointWorldToGraph(second);
|
|
return RectangleF.FromLTRB(System.Math.Min(a.X, b.X), System.Math.Min(a.Y, b.Y),
|
|
System.Math.Max(a.X, b.X), System.Math.Max(a.Y, b.Y));
|
|
}
|
|
|
|
private static void RunSta(System.Action action) =>
|
|
StaTestThread.Run(action, TimeSpan.FromSeconds(30), "Cut-off window selection test timed out.");
|
|
}
|