fix(engine): canonicalize PlaceBestFitPairs builds to match BestFitCache frame
This commit is contained in:
@@ -334,6 +334,12 @@ namespace OpenNest
|
||||
var bestFits = BestFitCache.GetOrCompute(
|
||||
item.Drawing, Plate.Size.Length, Plate.Size.Width, Plate.PartSpacing);
|
||||
|
||||
// BestFitCache stores pair coordinates in canonical frame. Build candidates
|
||||
// from a canonical drawing copy so geometry and coords share a frame; rebind
|
||||
// + un-rotate winning pair to the original drawing's frame before returning.
|
||||
var canonicalDrawing = CanonicalFrame.AsCanonicalCopy(item.Drawing);
|
||||
var sourceAngle = item.Drawing?.Source?.Angle ?? 0.0;
|
||||
|
||||
List<Part> bestPlacement = null;
|
||||
Box bestTarget = null;
|
||||
|
||||
@@ -342,7 +348,7 @@ namespace OpenNest
|
||||
if (!fit.Keep)
|
||||
continue;
|
||||
|
||||
var parts = fit.BuildParts(item.Drawing);
|
||||
var parts = fit.BuildParts(canonicalDrawing);
|
||||
var pairBbox = ((IEnumerable<IBoundable>)parts).GetBoundingBox();
|
||||
var pairW = pairBbox.Width;
|
||||
var pairL = pairBbox.Length;
|
||||
@@ -374,6 +380,10 @@ namespace OpenNest
|
||||
|
||||
if (bestPlacement == null) continue;
|
||||
|
||||
// Rebind to the original drawing and compose sourceAngle onto rotation so the
|
||||
// final placed parts sit in the user's visible frame.
|
||||
bestPlacement = RebindPairToOriginal(bestPlacement, item.Drawing, sourceAngle);
|
||||
|
||||
result.AddRange(bestPlacement);
|
||||
item.Quantity = 0;
|
||||
|
||||
@@ -388,6 +398,30 @@ namespace OpenNest
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rebinds each canonical-frame Part in the pair to the original Drawing at its current
|
||||
/// world pose, then composes sourceAngle onto each via CanonicalFrame.FromCanonical so
|
||||
/// the returned list is in the original drawing's visible frame. Mirrors
|
||||
/// DefaultNestEngine.RebindAndUnCanonicalize.
|
||||
/// </summary>
|
||||
private static List<Part> RebindPairToOriginal(List<Part> parts, Drawing original, double sourceAngle)
|
||||
{
|
||||
if (parts == null || parts.Count == 0)
|
||||
return parts;
|
||||
|
||||
for (var i = 0; i < parts.Count; i++)
|
||||
{
|
||||
var p = parts[i];
|
||||
var rebound = Part.CreateAtOrigin(original, p.Rotation);
|
||||
var delta = p.BoundingBox.Location - rebound.BoundingBox.Location;
|
||||
rebound.Offset(delta);
|
||||
rebound.UpdateBounds();
|
||||
parts[i] = rebound;
|
||||
}
|
||||
|
||||
return CanonicalFrame.FromCanonical(parts, sourceAngle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a drawing should use grid-fill (true) or bin-pack (false).
|
||||
/// Low-quantity items whose total area is a small fraction of the plate are
|
||||
|
||||
Reference in New Issue
Block a user