diff --git a/OpenNest.Core/CNC/SubProgramCall.cs b/OpenNest.Core/CNC/SubProgramCall.cs
index 07246f1..0c9223a 100644
--- a/OpenNest.Core/CNC/SubProgramCall.cs
+++ b/OpenNest.Core/CNC/SubProgramCall.cs
@@ -1,4 +1,5 @@
-using OpenNest.Math;
+using OpenNest.Geometry;
+using OpenNest.Math;
namespace OpenNest.CNC
{
@@ -35,6 +36,12 @@ namespace OpenNest.CNC
}
}
+ ///
+ /// Gets or sets the offset (position) at which the sub-program is executed.
+ /// For hole sub-programs, this is the hole center.
+ ///
+ public Vector Offset { get; set; }
+
///
/// Gets or sets the rotation of the program in degrees.
///
@@ -78,11 +85,13 @@ namespace OpenNest.CNC
///
public ICode Clone()
{
- return new SubProgramCall(program, Rotation);
+ return new SubProgramCall(program, Rotation) { Id = Id, Offset = Offset };
}
public override string ToString()
{
+ if (Offset.X != 0 || Offset.Y != 0)
+ return string.Format("G65 P{0} X{1} Y{2}", Id, Offset.X, Offset.Y);
return string.Format("G65 P{0} R{1}", Id, Rotation);
}
}
diff --git a/OpenNest.Tests/CuttingStrategy/HoleSubProgramTests.cs b/OpenNest.Tests/CuttingStrategy/HoleSubProgramTests.cs
new file mode 100644
index 0000000..dadc3c1
--- /dev/null
+++ b/OpenNest.Tests/CuttingStrategy/HoleSubProgramTests.cs
@@ -0,0 +1,43 @@
+using OpenNest.CNC;
+using OpenNest.Geometry;
+
+namespace OpenNest.Tests.CuttingStrategy;
+
+public class HoleSubProgramTests
+{
+ [Fact]
+ public void SubProgramCall_Offset_DefaultsToZero()
+ {
+ var call = new SubProgramCall();
+ Assert.Equal(0, call.Offset.X);
+ Assert.Equal(0, call.Offset.Y);
+ }
+
+ [Fact]
+ public void SubProgramCall_Offset_StoresValue()
+ {
+ var call = new SubProgramCall { Offset = new Vector(1.5, 2.5) };
+ Assert.Equal(1.5, call.Offset.X);
+ Assert.Equal(2.5, call.Offset.Y);
+ }
+
+ [Fact]
+ public void SubProgramCall_Clone_CopiesOffset()
+ {
+ var call = new SubProgramCall { Id = 1, Offset = new Vector(3, 4) };
+ var clone = (SubProgramCall)call.Clone();
+ Assert.Equal(3, clone.Offset.X);
+ Assert.Equal(4, clone.Offset.Y);
+ Assert.Equal(1, clone.Id);
+ }
+
+ [Fact]
+ public void SubProgramCall_ToString_IncludesOffset()
+ {
+ var call = new SubProgramCall { Id = 1000, Offset = new Vector(1.5, 2.5) };
+ var str = call.ToString();
+ Assert.Contains("P1000", str);
+ Assert.Contains("X1.5", str);
+ Assert.Contains("Y2.5", str);
+ }
+}