mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-04 16:01:35 -05:00
The cut-off line renderer paired codes as rapid/cut at even indices. A head-locked far-edge segment carries lock and unlock comments between its cuts, so its overcut was never dashed and later segments could fall out of step. Past the sheet only the dark part outline showed, which read as the line having lost its orange-red color. Walk the motions instead and draw each cut from the previous point. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
128 lines
4.7 KiB
C#
128 lines
4.7 KiB
C#
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using OpenNest.Controls;
|
|
using OpenNest.Geometry;
|
|
|
|
namespace OpenNest.WinForms.Tests;
|
|
|
|
public class CutOffDisplayTests
|
|
{
|
|
private static readonly Color OldLineGray = Color.FromArgb(64, 64, 64);
|
|
private static readonly Color CutoffLine = Color.OrangeRed;
|
|
private static readonly Color SelectedBlue = Color.FromArgb(0, 120, 255);
|
|
|
|
// A 100x100 quadrant-4 sheet puts a vertical cut-off at x=50 on the
|
|
// graph column x=50, rows 0..100 (PointWorldToGraph flips Y).
|
|
private static (PlateView View, CutOff Cutoff) BuildPlateWithCutOff()
|
|
{
|
|
var view = new PlateView(ColorSchemeRegistry.Get("Workshop"))
|
|
{
|
|
Size = new System.Drawing.Size(100, 100),
|
|
};
|
|
view.Matrix = new Matrix();
|
|
view.Plate.Size = new OpenNest.Geometry.Size(100, 100);
|
|
view.Plate.Quadrant = 4;
|
|
var cutoff = new CutOff(new Vector(50, 0), CutOffAxis.Vertical);
|
|
view.Plate.CutOffs.Add(cutoff);
|
|
view.Plate.RegenerateCutOffs(new CutOffSettings());
|
|
return (view, cutoff);
|
|
}
|
|
|
|
private static (int Orange, int White, int OldGray, int Blue) CountLinePixels(Bitmap image)
|
|
{
|
|
var orange = 0;
|
|
var white = 0;
|
|
var oldGray = 0;
|
|
var blue = 0;
|
|
|
|
for (var y = 3; y <= 96; y++)
|
|
{
|
|
for (var x = 48; x <= 52; x++)
|
|
{
|
|
var c = image.GetPixel(x, y);
|
|
|
|
if (c.R >= 200 && c.G <= 120 && c.B <= 80)
|
|
orange++;
|
|
else if (c.R >= 240 && c.G >= 240 && c.B >= 240)
|
|
white++;
|
|
else if (
|
|
System.Math.Abs(c.R - OldLineGray.R) <= 32
|
|
&& System.Math.Abs(c.G - OldLineGray.G) <= 32
|
|
&& System.Math.Abs(c.B - OldLineGray.B) <= 32
|
|
)
|
|
oldGray++;
|
|
else if (c.B >= 200 && c.R <= 60)
|
|
blue++;
|
|
}
|
|
}
|
|
|
|
return (orange, white, oldGray, blue);
|
|
}
|
|
|
|
[Fact]
|
|
public void CutOffLineIsDashedOrangeNotSolidBlack() => StaTestThread.Run(() =>
|
|
{
|
|
var (view, _) = BuildPlateWithCutOff();
|
|
using (view)
|
|
using (var image = new Bitmap(100, 100))
|
|
using (var g = Graphics.FromImage(image))
|
|
{
|
|
g.Clear(Color.White);
|
|
view.Renderer.DrawCutOffs(g);
|
|
|
|
var (orange, white, oldGray, _) = CountLinePixels(image);
|
|
Assert.True(orange >= 10, $"Expected the orange cut-off dash, found {orange} pixels.");
|
|
Assert.True(white >= 10, $"Expected dashed gaps along the cut-off line, found {white} white pixels.");
|
|
Assert.Equal(0, oldGray);
|
|
}
|
|
}, TimeSpan.FromMinutes(1), "Cut-off display test timed out.");
|
|
|
|
[Fact]
|
|
public void HeadLockedOvercutPastTheSheetIsDashedOrange() => StaTestThread.Run(() =>
|
|
{
|
|
// Quadrant 4's far edge for a vertical cut-off is the bottom (graph row 100); a 10
|
|
// overcut runs on to row 110, past the sheet.
|
|
var (view, cutoff) = BuildPlateWithCutOff();
|
|
using (view)
|
|
using (var image = new Bitmap(100, 130))
|
|
using (var g = Graphics.FromImage(image))
|
|
{
|
|
cutoff.HeadLockOvercut = 10;
|
|
view.Plate.RegenerateCutOffs(new CutOffSettings());
|
|
g.Clear(Color.White);
|
|
view.Renderer.DrawCutOffs(g);
|
|
|
|
var overcut = 0;
|
|
for (var y = 102; y <= 109; y++)
|
|
for (var x = 48; x <= 52; x++)
|
|
{
|
|
var c = image.GetPixel(x, y);
|
|
if (c.R >= 200 && c.G <= 120 && c.B <= 80)
|
|
overcut++;
|
|
}
|
|
Assert.True(overcut >= 4, $"Expected the orange dash on the overcut, found {overcut} pixels.");
|
|
var (orange, _, _, _) = CountLinePixels(image);
|
|
Assert.True(orange >= 10, $"Expected the orange dash on the sheet, found {orange} pixels.");
|
|
}
|
|
}, TimeSpan.FromMinutes(1), "Head-locked cut-off display test timed out.");
|
|
|
|
[Fact]
|
|
public void SelectedCutOffKeepsSolidBlueHighlight() => StaTestThread.Run(() =>
|
|
{
|
|
var (view, cutoff) = BuildPlateWithCutOff();
|
|
using (view)
|
|
{
|
|
view.Selection.SelectedCutOffs.Add(cutoff);
|
|
using var image = new Bitmap(100, 100);
|
|
using var g = Graphics.FromImage(image);
|
|
g.Clear(Color.White);
|
|
view.Renderer.DrawCutOffs(g);
|
|
|
|
var (orange, _, oldGray, blue) = CountLinePixels(image);
|
|
Assert.True(blue >= 20, $"Expected the solid blue selection line, found {blue} pixels.");
|
|
Assert.Equal(0, orange);
|
|
Assert.Equal(0, oldGray);
|
|
}
|
|
}, TimeSpan.FromMinutes(1), "Selected cut-off display test timed out.");
|
|
}
|