mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-07 08:45:43 -05:00
148 lines
5.4 KiB
C#
148 lines
5.4 KiB
C#
using System.Text;
|
|
using OpenNest.CNC;
|
|
using OpenNest.Geometry;
|
|
using OpenNest.Posts.Cincinnati;
|
|
using OpenNest.Posts.CincinnatiCIFiber;
|
|
|
|
namespace OpenNest.Tests.Cincinnati;
|
|
|
|
/// <summary>
|
|
/// Both Cincinnati posts raise the head before a rapid Plan Cutting marked to pass over parts
|
|
/// already cut, whatever the operator's head-raise settings; the CI Fiber post refuses the nest
|
|
/// while its head-raise block is not set.
|
|
/// </summary>
|
|
public class HeadRaisePostTests
|
|
{
|
|
private const string RaiseCode = "M210 (RAISE HEAD)";
|
|
|
|
[Theory]
|
|
[InlineData(M47Mode.None)]
|
|
[InlineData(M47Mode.BlockDelete)]
|
|
[InlineData(M47Mode.Auto)]
|
|
public void ClPost_RaisesBeforeAMarkedRapid_WhateverTheM47Mode(M47Mode mode)
|
|
{
|
|
var lines = ClLines(Nest(markSecond: true), mode);
|
|
|
|
var second = lines.FindIndex(l => l.Contains("G0 X10.75 Y1"));
|
|
Assert.True(second > 0, string.Join("\n", lines));
|
|
Assert.Equal("M47", lines[second - 1]);
|
|
}
|
|
|
|
[Fact]
|
|
public void ClPost_WithoutAMarker_FollowsTheM47Mode()
|
|
{
|
|
var lines = ClLines(Nest(markSecond: false), M47Mode.None);
|
|
|
|
var second = lines.FindIndex(l => l.Contains("G0 X10.75 Y1"));
|
|
Assert.True(second > 0, string.Join("\n", lines));
|
|
Assert.DoesNotContain("M47", lines[second - 1]);
|
|
}
|
|
|
|
[Fact]
|
|
public void CiFiberPost_WritesTheRaiseBeforeOnlyTheMarkedRapid()
|
|
{
|
|
var post = new CIFiberPostProcessor(new CIFiberPostConfig { HeadRaiseCode = RaiseCode });
|
|
using var stream = new MemoryStream();
|
|
post.Post(Nest(markSecond: true), stream);
|
|
var lines = Lines(stream);
|
|
|
|
var raise = Assert.Single(lines, l => l == RaiseCode);
|
|
Assert.Equal("G0X10.75Y1", lines[lines.IndexOf(raise) + 1]);
|
|
}
|
|
|
|
[Fact]
|
|
public void CiFiberPost_WithoutARaiseCode_RefusesAMarkedNest()
|
|
{
|
|
var post = new CIFiberPostProcessor(new CIFiberPostConfig());
|
|
|
|
var refusal = Assert.Throws<InvalidOperationException>(() => post.Post(Nest(markSecond: true), new MemoryStream()));
|
|
|
|
Assert.Contains("head-raise code", refusal.Message);
|
|
Assert.Contains("\"Head raise\" in the Cincinnati CI Fiber Settings dialog", refusal.Message);
|
|
post.Post(Nest(markSecond: false), new MemoryStream()); // Nothing marked: nothing to refuse.
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void ClPost_RaisesBeforeAMarkedHoleCall(bool marked)
|
|
{
|
|
var lines = ClLines(Nest(markSecond: marked, holedSecond: true), M47Mode.None);
|
|
|
|
var call = lines.FindIndex(l => l.Contains("G52 X12 Y1"));
|
|
Assert.True(call > 0, string.Join("\n", lines));
|
|
Assert.Equal(marked, lines[call - 1] == "M47");
|
|
}
|
|
|
|
[Fact]
|
|
public void CiFiberPost_WritesTheRaiseBeforeAMarkedHoleCallsRapid()
|
|
{
|
|
var post = new CIFiberPostProcessor(new CIFiberPostConfig { HeadRaiseCode = RaiseCode });
|
|
using var stream = new MemoryStream();
|
|
post.Post(Nest(markSecond: true, holedSecond: true), stream);
|
|
var lines = Lines(stream);
|
|
|
|
var raise = Assert.Single(lines, l => l == RaiseCode);
|
|
Assert.Equal("G0X12Y1", lines[lines.IndexOf(raise) + 1]);
|
|
}
|
|
|
|
// Two squares side by side, each with a line lead-in on its left; the second one's rapid
|
|
// marked. With holedSecond the second starts with a round hole cut as a sub-program, and the
|
|
// mark goes on its call.
|
|
private static Nest Nest(bool markSecond, bool holedSecond = false)
|
|
{
|
|
var nest = new Nest("RAISE");
|
|
var plate = new Plate(60, 120);
|
|
nest.Plates.Add(plate);
|
|
foreach (var x in new[] { 1.0, 11.0 })
|
|
{
|
|
var part = new Part(new Drawing("square", Square()), new Vector(x, 0));
|
|
var program = LeadIn();
|
|
if (holedSecond && x > 1)
|
|
program.Codes.Insert(0, new SubProgramCall { Id = 1, Program = Hole(), Offset = new Vector(1, 1) });
|
|
if (markSecond && x > 1)
|
|
program = HeadRaise.Mark(program, [0]);
|
|
Assert.True(part.RestoreLeadInProgram(program, true));
|
|
plate.Parts.Add(part);
|
|
}
|
|
return nest;
|
|
}
|
|
|
|
private static Program Square()
|
|
{
|
|
var p = new Program();
|
|
p.MoveTo(0, 0); p.LineTo(0, 2); p.LineTo(2, 2); p.LineTo(2, 0); p.LineTo(0, 0);
|
|
return p;
|
|
}
|
|
|
|
private static Program LeadIn()
|
|
{
|
|
var p = new Program();
|
|
p.MoveTo(-0.25, 1);
|
|
p.Codes.Add(new LinearMove(0, 1) { Layer = LayerType.Leadin });
|
|
p.LineTo(0, 2); p.LineTo(2, 2); p.LineTo(2, 0); p.LineTo(0, 0); p.LineTo(0, 1);
|
|
return p;
|
|
}
|
|
|
|
// A round hole of radius 0.25 around its sub-program's origin, entered from its center.
|
|
private static Program Hole()
|
|
{
|
|
var p = new Program();
|
|
p.MoveTo(0, 0);
|
|
p.Codes.Add(new LinearMove(0.25, 0) { Layer = LayerType.Leadin });
|
|
p.ArcTo(0.25, 0, 0, 0, RotationType.CCW);
|
|
return p;
|
|
}
|
|
|
|
private static List<string> ClLines(Nest nest, M47Mode mode)
|
|
{
|
|
var post = new CincinnatiPostProcessor(new CincinnatiPostConfig { RequireLibraries = false, ExteriorM47 = mode, InteriorM47 = mode });
|
|
using var stream = new MemoryStream();
|
|
post.Post(nest, stream);
|
|
return Lines(stream);
|
|
}
|
|
|
|
private static List<string> Lines(MemoryStream stream) =>
|
|
Encoding.UTF8.GetString(stream.ToArray()).Replace("\r\n", "\n").Split('\n').Select(l => l.Trim()).ToList();
|
|
}
|