feat: unify ActionAddPart into ActionClone and add group fill support
Merge ActionAddPart into ActionClone by adding a Drawing constructor, eliminating the redundant class. ActionClone now handles both adding new parts from a drawing and cloning selected part groups. Added Ctrl+F fill support for groups using FillLinear pattern tiling, and adopted quadrant-aware push directions from ActionAddPart. Refactored FillLinear to extract shared helpers and add a Fill(Pattern) overload for tiling arbitrary part groups across the work area. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,157 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
[DisplayName("Add Parts")]
|
||||
public class ActionAddPart : Action
|
||||
{
|
||||
private LayoutPart part;
|
||||
private double lastScale;
|
||||
|
||||
public ActionAddPart(PlateView plateView)
|
||||
: this(plateView, null)
|
||||
{
|
||||
}
|
||||
|
||||
public ActionAddPart(PlateView plateView, Drawing drawing)
|
||||
: base(plateView)
|
||||
{
|
||||
plateView.KeyDown += plateView_KeyDown;
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.MouseDown += plateView_MouseDown;
|
||||
plateView.Paint += plateView_Paint;
|
||||
|
||||
part = LayoutPart.Create(new Part(drawing), plateView);
|
||||
part.IsSelected = true;
|
||||
|
||||
lastScale = double.NaN;
|
||||
|
||||
plateView.SelectedParts.Clear();
|
||||
plateView.SelectedParts.Add(part);
|
||||
}
|
||||
|
||||
private void plateView_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
switch (e.Button)
|
||||
{
|
||||
case MouseButtons.Left:
|
||||
Apply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.KeyCode)
|
||||
{
|
||||
case Keys.F1:
|
||||
case Keys.Enter:
|
||||
Apply();
|
||||
break;
|
||||
|
||||
case Keys.F:
|
||||
if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
|
||||
Fill();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (plateView.ViewScale != lastScale)
|
||||
{
|
||||
part.Update(plateView);
|
||||
part.Draw(e.Graphics);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (part.IsDirty)
|
||||
part.Update(plateView);
|
||||
|
||||
part.Draw(e.Graphics);
|
||||
}
|
||||
|
||||
lastScale = plateView.ViewScale;
|
||||
}
|
||||
|
||||
private void plateView_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var offset = plateView.CurrentPoint - part.BoundingBox.Location;
|
||||
part.Offset(offset);
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override void DisconnectEvents()
|
||||
{
|
||||
plateView.KeyDown -= plateView_KeyDown;
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.MouseDown -= plateView_MouseDown;
|
||||
plateView.Paint -= plateView_Paint;
|
||||
|
||||
plateView.SelectedParts.Clear();
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override void CancelAction()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsBusy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Fill()
|
||||
{
|
||||
var boxes = new List<Box>();
|
||||
|
||||
foreach (var part in plateView.Plate.Parts)
|
||||
boxes.Add(part.BoundingBox.Offset(plateView.Plate.PartSpacing));
|
||||
|
||||
var bounds = plateView.Plate.WorkArea();
|
||||
|
||||
var vbox = Helper.GetLargestBoxVertically(plateView.CurrentPoint, bounds, boxes);
|
||||
var hbox = Helper.GetLargestBoxHorizontally(plateView.CurrentPoint, bounds, boxes);
|
||||
|
||||
var box = vbox.Area() > hbox.Area() ? vbox : hbox;
|
||||
|
||||
var engine = new NestEngine(plateView.Plate);
|
||||
engine.FillArea(box, new NestItem { Drawing = this.part.BasePart.BaseDrawing });
|
||||
}
|
||||
|
||||
private void Apply()
|
||||
{
|
||||
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
|
||||
{
|
||||
switch (plateView.Plate.Quadrant)
|
||||
{
|
||||
case 1:
|
||||
plateView.PushSelected(PushDirection.Left);
|
||||
plateView.PushSelected(PushDirection.Down);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
plateView.PushSelected(PushDirection.Right);
|
||||
plateView.PushSelected(PushDirection.Down);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
plateView.PushSelected(PushDirection.Right);
|
||||
plateView.PushSelected(PushDirection.Up);
|
||||
break;
|
||||
case 4:
|
||||
plateView.PushSelected(PushDirection.Left);
|
||||
plateView.PushSelected(PushDirection.Up);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
plateView.Plate.Parts.Add(part.BasePart.Clone() as Part);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
using OpenNest.Geometry;
|
||||
@@ -13,6 +14,11 @@ namespace OpenNest.Actions
|
||||
|
||||
private double lastScale;
|
||||
|
||||
public ActionClone(PlateView plateView, Drawing drawing)
|
||||
: this(plateView, new List<Part> { new Part(drawing) })
|
||||
{
|
||||
}
|
||||
|
||||
public ActionClone(PlateView plateView, List<Part> partsToClone)
|
||||
: base(plateView)
|
||||
{
|
||||
@@ -53,6 +59,11 @@ namespace OpenNest.Actions
|
||||
case Keys.Enter:
|
||||
Apply();
|
||||
break;
|
||||
|
||||
case Keys.F:
|
||||
if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
|
||||
Fill();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,11 +122,38 @@ namespace OpenNest.Actions
|
||||
{
|
||||
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
|
||||
{
|
||||
plateView.PushSelected(PushDirection.Left);
|
||||
plateView.PushSelected(PushDirection.Down);
|
||||
switch (plateView.Plate.Quadrant)
|
||||
{
|
||||
case 1:
|
||||
plateView.PushSelected(PushDirection.Left);
|
||||
plateView.PushSelected(PushDirection.Down);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
plateView.PushSelected(PushDirection.Right);
|
||||
plateView.PushSelected(PushDirection.Down);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
plateView.PushSelected(PushDirection.Right);
|
||||
plateView.PushSelected(PushDirection.Up);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
plateView.PushSelected(PushDirection.Left);
|
||||
plateView.PushSelected(PushDirection.Up);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parts.ForEach(p => plateView.Plate.Parts.Add(p.BasePart.Clone() as Part));
|
||||
}
|
||||
|
||||
private void Fill()
|
||||
{
|
||||
var engine = new NestEngine(plateView.Plate);
|
||||
var groupParts = parts.Select(p => p.BasePart).ToList();
|
||||
engine.Fill(groupParts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,7 +687,7 @@ namespace OpenNest.Forms
|
||||
if (drawing == null)
|
||||
return;
|
||||
|
||||
PlateView.SetAction(typeof(ActionAddPart), drawing);
|
||||
PlateView.SetAction(typeof(ActionClone), drawing);
|
||||
|
||||
addPart = false;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Actions\Action.cs" />
|
||||
<Compile Include="Actions\ActionAddPart.cs" />
|
||||
<Compile Include="Actions\ActionClone.cs" />
|
||||
<Compile Include="Actions\ActionFillArea.cs" />
|
||||
<Compile Include="Actions\ActionSelect.cs" />
|
||||
|
||||
Reference in New Issue
Block a user