fix(engine): leave scribe marks out of layout bounds and salvage
The job runner already checked sheet bounds on material contours only, but the benchmark validator and salvage scoring used Part.BoundingBox, which includes scribe/etch moves. A PEP bend tick that ends a hair past the part's edge passed the runner yet failed the benchmark when placed flush to the sheet edge, and it could shrink the credited offcut. Marks only mark the surface, so bounds and salvage now use material only. Benchmark before/after (all five built-in engines, local fixtures, salvage 0.5): no job changed validity or cost. Regression tests pin the new rule: a protruding tick flush to the sheet edge is valid in all four quadrants, and a tick past the parts envelope no longer shrinks salvage (targeted fixture cost 130 -> 120). Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@ public static class NestJobCost
|
||||
/// <summary>
|
||||
/// Sheet area less SalvageRate times the largest usable full-width/full-length edge offcut.
|
||||
/// Both offcut dimensions must meet MinimumSalvageDimension, which must be positive.
|
||||
/// Bounds intentionally use Part.BoundingBox (including marks) to preserve benchmark scores.
|
||||
/// Bounds use rotated material contours only; scribe/etch marks never shrink salvage offcuts.
|
||||
/// </summary>
|
||||
public static double NetSheetArea(NestJob job, NestJobPlateResult sheet)
|
||||
{
|
||||
@@ -26,7 +26,7 @@ public static class NestJobCost
|
||||
part.Rotate(p.Rotation);
|
||||
part.Location = new OpenNest.Geometry.Vector(p.X, p.Y);
|
||||
part.UpdateBounds();
|
||||
return part.BoundingBox;
|
||||
return NestLayoutCheck.MaterialBounds(part);
|
||||
})
|
||||
.ToList();
|
||||
return NetSheetArea(job.Options, sheet.Stock, boxes.Min(b => b.Left),
|
||||
@@ -35,7 +35,7 @@ public static class NestJobCost
|
||||
|
||||
/// <summary>
|
||||
/// Computes net area from an existing placed-parts envelope without rebuilding geometry.
|
||||
/// For benchmark parity the envelope must include the same marks as Part.BoundingBox.
|
||||
/// The envelope must contain material only; exclude scribe/etch marks.
|
||||
/// Empty sheets should use the sheet overload, which returns their full area.
|
||||
/// </summary>
|
||||
public static double NetSheetArea(NestJobOptions options, NestPlateStock stock, Box partsEnvelope) =>
|
||||
|
||||
Reference in New Issue
Block a user