perf: add CloneAtOffset to skip re-rotation and bbox walk on part clones
Part.Clone() re-clones from the drawing's unrotated program, re-rotates, and walks all CNC codes twice for bounding box — 4 O(c) passes per clone. CloneAtOffset clones from the already-rotated program and computes the bounding box arithmetically, reducing to 1 O(c) pass per clone. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -208,5 +208,29 @@ namespace OpenNest
|
|||||||
|
|
||||||
return part;
|
return part;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates an offset copy of the part. Clones from the already-rotated
|
||||||
|
/// program (skips re-rotation) and computes the bounding box arithmetically
|
||||||
|
/// (skips Program.BoundingBox walk).
|
||||||
|
/// </summary>
|
||||||
|
public Part CloneAtOffset(Vector offset)
|
||||||
|
{
|
||||||
|
var clonedProgram = Program.Clone() as Program;
|
||||||
|
var part = new Part(BaseDrawing, clonedProgram,
|
||||||
|
location + offset,
|
||||||
|
new Box(BoundingBox.X + offset.X, BoundingBox.Y + offset.Y,
|
||||||
|
BoundingBox.Width, BoundingBox.Height));
|
||||||
|
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Part(Drawing baseDrawing, Program program, Vector location, Box boundingBox)
|
||||||
|
{
|
||||||
|
BaseDrawing = baseDrawing;
|
||||||
|
Program = program;
|
||||||
|
this.location = location;
|
||||||
|
BoundingBox = boundingBox;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,8 +76,7 @@ namespace OpenNest
|
|||||||
var pushDir = GetPushDirection(direction);
|
var pushDir = GetPushDirection(direction);
|
||||||
var opposite = Helper.OppositeDirection(pushDir);
|
var opposite = Helper.OppositeDirection(pushDir);
|
||||||
|
|
||||||
var partB = (Part)partA.Clone();
|
var partB = partA.CloneAtOffset(MakeOffset(direction, bboxDim));
|
||||||
partB.Offset(MakeOffset(direction, bboxDim));
|
|
||||||
|
|
||||||
var movingLines = boundary.GetLines(partB.Location, pushDir);
|
var movingLines = boundary.GetLines(partB.Location, pushDir);
|
||||||
var stationaryLines = boundary.GetLines(partA.Location, opposite);
|
var stationaryLines = boundary.GetLines(partA.Location, opposite);
|
||||||
@@ -364,8 +363,7 @@ namespace OpenNest
|
|||||||
if (nextPos + dim > limit + Tolerance.Epsilon)
|
if (nextPos + dim > limit + Tolerance.Epsilon)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
var clone = (Part)template.Clone();
|
var clone = template.CloneAtOffset(MakeOffset(direction, copyDistance * count));
|
||||||
clone.Offset(MakeOffset(direction, copyDistance * count));
|
|
||||||
seed.Parts.Add(clone);
|
seed.Parts.Add(clone);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,7 @@ namespace OpenNest
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
foreach (var part in Parts)
|
foreach (var part in Parts)
|
||||||
{
|
pattern.Parts.Add(part.CloneAtOffset(offset));
|
||||||
var clone = (Part)part.Clone();
|
|
||||||
clone.Offset(offset);
|
|
||||||
pattern.Parts.Add(clone);
|
|
||||||
}
|
|
||||||
|
|
||||||
pattern.UpdateBounds();
|
pattern.UpdateBounds();
|
||||||
return pattern;
|
return pattern;
|
||||||
|
|||||||
Reference in New Issue
Block a user