mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-10 21:21:09 -05:00
Clicking and window selection paired the cut-off program's codes as rapid/cut at even positions. A head-locked far-edge segment carries lock comments (and, cut from the far edge, a rapid return) between its cuts, so no pair matched and the line could not be selected, though it drew. CutOff.CutStrokes now walks the motions once for the renderer, click hit test, window selection and the Sheet Cut-Off preview, so what is selectable matches what is drawn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
122 lines
4.0 KiB
C#
122 lines
4.0 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using OpenNest.CNC;
|
|
using OpenNest.Engine.Sequencing;
|
|
using OpenNest.Geometry;
|
|
using OpenNest.Undo;
|
|
|
|
namespace OpenNest.Controls
|
|
{
|
|
internal class CutOffHandler
|
|
{
|
|
private readonly PlateView view;
|
|
private Dictionary<Part, Geometry.Entity> dragPerimeterCache;
|
|
|
|
// Open from the press on a cut-off to the release: a drag undoes as one move.
|
|
private ChangeScope drag;
|
|
|
|
// The lines that meet the dragged cut-off and follow it.
|
|
private CutOffJoints joints;
|
|
private bool moved;
|
|
|
|
public CutOffHandler(PlateView view)
|
|
{
|
|
this.view = view;
|
|
}
|
|
|
|
public bool IsDragging { get; private set; }
|
|
|
|
/// <summary>Whether Sheet Cut-Off draws full-length lines instead of stopping at the first crossing.</summary>
|
|
public bool FullLengthNewLines { get; set; }
|
|
|
|
public CutOff TryStartDrag(Vector point, double tolerance)
|
|
{
|
|
var hitCutOff = GetCutOffAtPoint(point, tolerance);
|
|
if (hitCutOff == null)
|
|
return null;
|
|
|
|
IsDragging = true;
|
|
dragPerimeterCache = Plate.BuildPerimeterCache(view.Plate);
|
|
joints = CutOffTrim.Joints(view.Plate, hitCutOff, view.CutOffSettings);
|
|
moved = false;
|
|
drag = view.BeginChange("Move Cut-Off");
|
|
return hitCutOff;
|
|
}
|
|
|
|
public void UpdateDrag(Vector currentPoint, CutOff cutOff)
|
|
{
|
|
if (!IsDragging || cutOff == null)
|
|
return;
|
|
|
|
drag?.MarkChanged();
|
|
if (cutOff.Axis == CutOffAxis.Vertical)
|
|
cutOff.Position = new Vector(currentPoint.X, cutOff.Position.Y);
|
|
else
|
|
cutOff.Position = new Vector(cutOff.Position.X, currentPoint.Y);
|
|
|
|
cutOff.Regenerate(view.Plate, view.CutOffSettings, dragPerimeterCache);
|
|
moved = true;
|
|
joints?.MoveTo(cutOff.Axis == CutOffAxis.Vertical ? cutOff.Position.X : cutOff.Position.Y);
|
|
foreach (var line in joints?.Lines ?? new List<CutOff>())
|
|
line.Regenerate(view.Plate, view.CutOffSettings, dragPerimeterCache);
|
|
view.Invalidate();
|
|
}
|
|
|
|
public void EndDrag()
|
|
{
|
|
if (!IsDragging)
|
|
return;
|
|
|
|
IsDragging = false;
|
|
dragPerimeterCache = null;
|
|
view.Plate.RegenerateCutOffs(view.CutOffSettings);
|
|
if (moved && joints != null)
|
|
PlateSequencing.PlaceCutOffs(view.Plate, joints.Lines);
|
|
joints = null;
|
|
view.Invalidate();
|
|
|
|
var scope = drag;
|
|
drag = null;
|
|
scope?.Complete();
|
|
scope?.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applies a trim, extend or swap as one undoable change: the new limits, regenerated
|
|
/// cut-offs, and the changed cut-offs' segments placed where the cut-off rules need them.
|
|
/// False, changing nothing, when the edit was refused.
|
|
/// </summary>
|
|
public bool Apply(CutOffEdit edit, string label)
|
|
{
|
|
if (edit == null || !edit.Succeeded)
|
|
return false;
|
|
|
|
using var change = view.BeginChange(label);
|
|
change.MarkChanged();
|
|
edit.Apply();
|
|
view.Plate.RegenerateCutOffs(view.CutOffSettings);
|
|
PlateSequencing.PlaceCutOffs(view.Plate, edit.Changes.Select(c => c.CutOff));
|
|
view.Invalidate();
|
|
change.Complete();
|
|
return true;
|
|
}
|
|
|
|
public CutOff GetCutOffAtPoint(Vector point, double tolerance)
|
|
{
|
|
if (view.Plate?.CutOffs == null)
|
|
return null;
|
|
|
|
foreach (var cutoff in view.Plate.CutOffs)
|
|
{
|
|
foreach (var line in CutOff.CutStrokes(cutoff.Drawing?.Program))
|
|
{
|
|
if (line.ClosestPointTo(point).DistanceTo(point) <= tolerance)
|
|
return cutoff;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|