perf(fill): reuse offset geometry for translated copies
FillLinear re-prepared offset perimeter geometry (ConvertProgram -> ShapeProfile -> OffsetOutward) for every part it measured, although tiled copies share one Program and differ only by Location. A CPU profile of a 169-part Default job put 62% of wall time there. Prepare each distinct Program (reference identity) once per public Fill/FillRow call in local frame, then clone and translate for each location. The cache is created per call and passed down privately because FillHelpers.FillPattern calls Fill concurrently on one instance. PartGeometry gains a local-frame Program overload that the Part overload now delegates to. Evaluation order, lazy preparation, fallbacks and tiling are unchanged. Differential tests against a frozen copy of the previous FillLinear check bitwise equality, including concurrent calls; Debug work tests pin preparation counts. With the thread pool capped at one worker, before/after whole-job layouts are byte-identical. The Default corpus job median drops from 40,715 to 18,810 ms.
This commit is contained in:
@@ -52,9 +52,21 @@ namespace OpenNest
|
||||
/// without tessellation, which keeps arc-heavy parts fast in directional-distance loops.
|
||||
/// </summary>
|
||||
public static List<Entity> GetOffsetPerimeterEntities(Part part, double spacing)
|
||||
{
|
||||
var entities = GetOffsetPerimeterEntities(part.Program, spacing);
|
||||
foreach (var entity in entities)
|
||||
entity.Offset(part.Location);
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares a fresh offset perimeter in the program's local frame, without translation.
|
||||
/// </summary>
|
||||
public static List<Entity> GetOffsetPerimeterEntities(CNC.Program program, double spacing)
|
||||
{
|
||||
PerfCounters.CountOffsetPerimeterEntities();
|
||||
var geoEntities = ConvertProgram.ToGeometry(part.Program);
|
||||
var geoEntities = ConvertProgram.ToGeometry(program);
|
||||
var profile = new ShapeProfile(
|
||||
geoEntities.Where(e => SpecialLayers.IsMaterial(e.Layer)).ToList()
|
||||
);
|
||||
@@ -63,11 +75,6 @@ namespace OpenNest
|
||||
if (offsetShape == null)
|
||||
return new List<Entity>();
|
||||
|
||||
// Offset the shape's entities to the part's location.
|
||||
// OffsetOutward creates a new Shape, so mutating is safe.
|
||||
foreach (var entity in offsetShape.Entities)
|
||||
entity.Offset(part.Location);
|
||||
|
||||
return offsetShape.Entities;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user