feat: PP钻带基础信息显示X/Y间距

检测PP钻带(文件名-pp结尾、4孔、直径4.000),计算上下孔X间距和左右孔Y间距
(欧氏距离),在MainWindow和StartupSelectionWindow的基础信息中显示。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 16:04:51 +08:00
parent 9896e54e93
commit cb27e8917a
6 changed files with 192 additions and 5 deletions

View File

@@ -33,6 +33,9 @@ namespace DrillTools
private bool _isStartupDrillTapeFile;
private bool _canGeneratePpDrillTape;
private bool _shouldCheckSortFileOnLoad = true;
private bool _isPpDrillTape;
private double _ppXSpacing;
private double _ppYSpacing;
private const int SwRestore = 9;
private const int SvsiSelect = 0x1;
@@ -209,6 +212,33 @@ namespace DrillTools
set => SetProperty(ref _minEADiameter, value);
}
/// <summary>
/// 是否为PP钻带
/// </summary>
public bool IsPpDrillTape
{
get => _isPpDrillTape;
set => SetProperty(ref _isPpDrillTape, value);
}
/// <summary>
/// PP钻带X间距左右孔距离单位mm
/// </summary>
public double PpXSpacing
{
get => _ppXSpacing;
set => SetProperty(ref _ppXSpacing, value);
}
/// <summary>
/// PP钻带Y间距上下孔距离单位mm
/// </summary>
public double PpYSpacing
{
get => _ppYSpacing;
set => SetProperty(ref _ppYSpacing, value);
}
/// <summary>
/// 从钻带内容加载刀具信息
/// </summary>
@@ -316,6 +346,9 @@ namespace DrillTools
// 计算并更新最小直径信息
UpdateMinDiameterInfo();
// 计算PP钻带间距
UpdatePpSpacingInfo();
// 启动菜单的预检查和非调整刀序动作会关闭此开关,避免排序提示抢在菜单前弹出。
if (ShouldCheckSortFileOnLoad && !string.IsNullOrEmpty(OriginalFilePath))
{
@@ -1709,6 +1742,99 @@ M30";
System.Diagnostics.Debug.WriteLine($"=== 计算完成 ===");
}
/// <summary>
/// 更新PP钻带间距信息
/// </summary>
private void UpdatePpSpacingInfo()
{
IsPpDrillTape = false;
PpXSpacing = 0;
PpYSpacing = 0;
// 检测条件:文件名以-pp结尾恰好1个刀具4个孔直径4.000
if (string.IsNullOrEmpty(OriginalFilePath))
return;
var fileName = System.IO.Path.GetFileNameWithoutExtension(OriginalFilePath);
if (!fileName.EndsWith("-pp", StringComparison.OrdinalIgnoreCase))
return;
if (Tools.Count != 1)
return;
var tool = Tools[0];
if (tool.TotalHoles != 4 || Math.Abs(tool.Diameter - 4.000) > 0.001)
return;
// 解析孔位坐标
var points = new List<(double X, double Y)>();
foreach (var location in tool.HoleLocations)
{
var match = System.Text.RegularExpressions.Regex.Match(location, @"X([+-]?\d+)Y([+-]?\d+)");
if (match.Success)
{
double x = double.Parse(match.Groups[1].Value) / 1000.0;
double y = double.Parse(match.Groups[2].Value) / 1000.0;
points.Add((x, y));
}
}
if (points.Count != 4)
return;
IsPpDrillTape = true;
// 将4个点配对为矩形的两组对边取X跨度+Y跨度最大的方案
int[][][] combos = { new[] { new[] { 0, 1 }, new[] { 2, 3 } }, new[] { new[] { 0, 2 }, new[] { 1, 3 } }, new[] { new[] { 0, 3 }, new[] { 1, 2 } } };
double bestRange = -1;
int bestIdx = 0;
for (int i = 0; i < combos.Length; i++)
{
var a = points[combos[i][0][0]];
var b = points[combos[i][0][1]];
var c = points[combos[i][1][0]];
var d = points[combos[i][1][1]];
double xRange = Math.Max(Math.Abs(a.X - b.X), Math.Abs(c.X - d.X));
double yRange = Math.Max(Math.Abs(a.Y - b.Y), Math.Abs(c.Y - d.Y));
double totalRange = xRange + yRange;
if (totalRange > bestRange)
{
bestRange = totalRange;
bestIdx = i;
}
}
var p1 = points[combos[bestIdx][0][0]];
var p2 = points[combos[bestIdx][0][1]];
var p3 = points[combos[bestIdx][1][0]];
var p4 = points[combos[bestIdx][1][1]];
double dist1 = Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y));
double dist2 = Math.Sqrt((p3.X - p4.X) * (p3.X - p4.X) + (p3.Y - p4.Y) * (p3.Y - p4.Y));
// 跨度更大的为X间距上下孔另一组为Y间距左右孔
double xSpan1 = Math.Abs(p1.X - p2.X);
double xSpan2 = Math.Abs(p3.X - p4.X);
if (xSpan1 >= xSpan2)
{
PpXSpacing = Math.Round(dist1, 3, MidpointRounding.AwayFromZero);
PpYSpacing = Math.Round(dist2, 3, MidpointRounding.AwayFromZero);
}
else
{
PpXSpacing = Math.Round(dist2, 3, MidpointRounding.AwayFromZero);
PpYSpacing = Math.Round(dist1, 3, MidpointRounding.AwayFromZero);
}
System.Diagnostics.Debug.WriteLine($"[PP钻带] X间距={PpXSpacing:F3}, Y间距={PpYSpacing:F3}");
}
/// <summary>
/// 测试使用参考钻带重排功能
/// </summary>