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

@@ -37,7 +37,8 @@ namespace DrillTools
bool canClearParameters = CanClearDrillTapeParameters(filePath); bool canClearParameters = CanClearDrillTapeParameters(filePath);
bool canGeneratePpDrillTape = CanGeneratePpDrillTape(filePath); bool canGeneratePpDrillTape = CanGeneratePpDrillTape(filePath);
GetMinDiameters(filePath, out double minDrill, out double minSlot, out double minEA); GetMinDiameters(filePath, out double minDrill, out double minSlot, out double minEA);
var selectionWindow = new StartupSelectionWindow(filePath, canClearParameters, canGeneratePpDrillTape, minDrill, minSlot, minEA); GetPpSpacing(filePath, out bool isPpDrillTape, out double ppXSpacing, out double ppYSpacing);
var selectionWindow = new StartupSelectionWindow(filePath, canClearParameters, canGeneratePpDrillTape, minDrill, minSlot, minEA, isPpDrillTape, ppXSpacing, ppYSpacing);
selectionWindow.ShowDialog(); selectionWindow.ShowDialog();
switch (selectionWindow.SelectedAction) switch (selectionWindow.SelectedAction)
@@ -173,6 +174,32 @@ namespace DrillTools
} }
} }
private static void GetPpSpacing(string filePath, out bool isPpDrillTape, out double ppXSpacing, out double ppYSpacing)
{
isPpDrillTape = false;
ppXSpacing = 0;
ppYSpacing = 0;
try
{
var viewModel = new MainWindowViewModel
{
OriginalFilePath = filePath,
ShouldCheckSortFileOnLoad = false
};
string content = CommandTypeFileReader.ReadAllText(filePath);
viewModel.LoadToolsFromDrillTape(content);
isPpDrillTape = viewModel.IsPpDrillTape;
ppXSpacing = viewModel.PpXSpacing;
ppYSpacing = viewModel.PpYSpacing;
}
catch
{
}
}
private static void PerformPpDrillTapeGeneration(string filePath) private static void PerformPpDrillTapeGeneration(string filePath)
{ {
try try

View File

@@ -211,10 +211,20 @@
<StackPanel Grid.Column="0" Orientation="Horizontal"> <StackPanel Grid.Column="0" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="文件名:" /> <TextBlock VerticalAlignment="Center" Text="文件名:" />
<TextBlock <TextBlock
Margin="0,0,0,5" Margin="0,0,10,5"
VerticalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" FontWeight="Bold"
Text="{Binding FileNameWithoutExtension}" /> Text="{Binding FileNameWithoutExtension}" />
<TextBlock
Margin="10,0,0,5"
VerticalAlignment="Center"
Visibility="{Binding IsPpDrillTape, Converter={StaticResource BooleanToVisibilityConverter}}"
Text="{Binding PpXSpacing, StringFormat=X间距: {0:F3}}" />
<TextBlock
Margin="10,0,0,5"
VerticalAlignment="Center"
Visibility="{Binding IsPpDrillTape, Converter={StaticResource BooleanToVisibilityConverter}}"
Text="{Binding PpYSpacing, StringFormat=Y间距: {0:F3}}" />
</StackPanel> </StackPanel>
<!-- 三个最小直径信息在同一行 --> <!-- 三个最小直径信息在同一行 -->

View File

@@ -33,6 +33,9 @@ namespace DrillTools
private bool _isStartupDrillTapeFile; private bool _isStartupDrillTapeFile;
private bool _canGeneratePpDrillTape; private bool _canGeneratePpDrillTape;
private bool _shouldCheckSortFileOnLoad = true; private bool _shouldCheckSortFileOnLoad = true;
private bool _isPpDrillTape;
private double _ppXSpacing;
private double _ppYSpacing;
private const int SwRestore = 9; private const int SwRestore = 9;
private const int SvsiSelect = 0x1; private const int SvsiSelect = 0x1;
@@ -209,6 +212,33 @@ namespace DrillTools
set => SetProperty(ref _minEADiameter, value); 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>
/// 从钻带内容加载刀具信息 /// 从钻带内容加载刀具信息
/// </summary> /// </summary>
@@ -316,6 +346,9 @@ namespace DrillTools
// 计算并更新最小直径信息 // 计算并更新最小直径信息
UpdateMinDiameterInfo(); UpdateMinDiameterInfo();
// 计算PP钻带间距
UpdatePpSpacingInfo();
// 启动菜单的预检查和非调整刀序动作会关闭此开关,避免排序提示抢在菜单前弹出。 // 启动菜单的预检查和非调整刀序动作会关闭此开关,避免排序提示抢在菜单前弹出。
if (ShouldCheckSortFileOnLoad && !string.IsNullOrEmpty(OriginalFilePath)) if (ShouldCheckSortFileOnLoad && !string.IsNullOrEmpty(OriginalFilePath))
{ {
@@ -1709,6 +1742,99 @@ M30";
System.Diagnostics.Debug.WriteLine($"=== 计算完成 ==="); 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>
/// 测试使用参考钻带重排功能 /// 测试使用参考钻带重排功能
/// </summary> /// </summary>

View File

@@ -24,10 +24,20 @@
<StackPanel Grid.Row="0" Orientation="Horizontal"> <StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="文件名:" /> <TextBlock VerticalAlignment="Center" Text="文件名:" />
<TextBlock <TextBlock
Margin="0,0,0,5" Margin="0,0,10,5"
VerticalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" FontWeight="Bold"
Text="{Binding FileName}" /> Text="{Binding FileName}" />
<TextBlock
Margin="10,0,0,5"
VerticalAlignment="Center"
Visibility="{Binding IsPpDrillTape, Converter={StaticResource BooleanToVisibilityConverter}}"
Text="{Binding PpXSpacing, StringFormat=X间距: {0:F3}}" />
<TextBlock
Margin="10,0,0,5"
VerticalAlignment="Center"
Visibility="{Binding IsPpDrillTape, Converter={StaticResource BooleanToVisibilityConverter}}"
Text="{Binding PpYSpacing, StringFormat=Y间距: {0:F3}}" />
</StackPanel> </StackPanel>
<Grid Grid.Row="1"> <Grid Grid.Row="1">

View File

@@ -17,7 +17,8 @@ namespace DrillTools
public StartupAction SelectedAction { get; private set; } = StartupAction.None; public StartupAction SelectedAction { get; private set; } = StartupAction.None;
public StartupSelectionWindow(string filePath, bool canClearParameters = false, bool canGeneratePpDrillTape = false, public StartupSelectionWindow(string filePath, bool canClearParameters = false, bool canGeneratePpDrillTape = false,
double minDrillDiameter = 0, double minSlotDiameter = 0, double minEADiameter = 0) double minDrillDiameter = 0, double minSlotDiameter = 0, double minEADiameter = 0,
bool isPpDrillTape = false, double ppXSpacing = 0, double ppYSpacing = 0)
{ {
InitializeComponent(); InitializeComponent();
DataContext = new DataContext = new
@@ -25,7 +26,10 @@ namespace DrillTools
FileName = Path.GetFileNameWithoutExtension(filePath), FileName = Path.GetFileNameWithoutExtension(filePath),
MinDrillDiameter = minDrillDiameter, MinDrillDiameter = minDrillDiameter,
MinSlotDiameter = minSlotDiameter, MinSlotDiameter = minSlotDiameter,
MinEADiameter = minEADiameter MinEADiameter = minEADiameter,
IsPpDrillTape = isPpDrillTape,
PpXSpacing = ppXSpacing,
PpYSpacing = ppYSpacing
}; };
ClearParametersButton.Visibility = canClearParameters ? Visibility.Visible : Visibility.Collapsed; ClearParametersButton.Visibility = canClearParameters ? Visibility.Visible : Visibility.Collapsed;
GeneratePpDrillTapeButton.Visibility = canGeneratePpDrillTape ? Visibility.Visible : Visibility.Collapsed; GeneratePpDrillTapeButton.Visibility = canGeneratePpDrillTape ? Visibility.Visible : Visibility.Collapsed;

View File

@@ -0,0 +1,10 @@
M48
;厚铜板参数-镀膜-EA-260417
T01C4.000H00400Z-0.305S020.00F030.0U0700.0
%
T01
X245000Y297500
X023000Y595000
X-245000Y297500
X030000Y000000
M30