diff --git a/OpenNest.Engine/OpenNest.Engine.csproj b/OpenNest.Engine/OpenNest.Engine.csproj
index 03e28a8..ee66de5 100644
--- a/OpenNest.Engine/OpenNest.Engine.csproj
+++ b/OpenNest.Engine/OpenNest.Engine.csproj
@@ -45,6 +45,7 @@
+
diff --git a/OpenNest.Engine/Pattern.cs b/OpenNest.Engine/Pattern.cs
new file mode 100644
index 0000000..1cdb2e4
--- /dev/null
+++ b/OpenNest.Engine/Pattern.cs
@@ -0,0 +1,57 @@
+using System.Collections.Generic;
+using OpenNest.Geometry;
+
+namespace OpenNest
+{
+ public class Pattern
+ {
+ public Pattern()
+ {
+ Parts = new List();
+ }
+
+ public List Parts { get; }
+
+ public Box BoundingBox { get; private set; }
+
+ public void UpdateBounds()
+ {
+ BoundingBox = Parts.GetBoundingBox();
+ }
+
+ public List GetLines(PushDirection facingDirection)
+ {
+ var lines = new List();
+
+ foreach (var part in Parts)
+ lines.AddRange(Helper.GetPartLines(part, facingDirection));
+
+ return lines;
+ }
+
+ public List GetOffsetLines(double spacing, PushDirection facingDirection)
+ {
+ var lines = new List();
+
+ foreach (var part in Parts)
+ lines.AddRange(Helper.GetOffsetPartLines(part, spacing, facingDirection));
+
+ return lines;
+ }
+
+ public Pattern Clone(Vector offset)
+ {
+ var pattern = new Pattern();
+
+ foreach (var part in Parts)
+ {
+ var clone = (Part)part.Clone();
+ clone.Offset(offset);
+ pattern.Parts.Add(clone);
+ }
+
+ pattern.UpdateBounds();
+ return pattern;
+ }
+ }
+}