钻带解析顺序与格式优化,界面信息增强

本次更新聚焦于钻带文件解析顺序与格式的准确还原,提升了界面基础信息展示,并优化了相关数据结构和辅助方法。主要包括:
- 钻带孔位逐行顺序解析,完整保留原始坐标字符串格式,避免顺序错乱和格式丢失。
- 界面新增基础信息分组,自动统计并展示最小钻咀、槽刀、EA刀直径。
- 数据结构如Point2D等增加运算符重载和构造函数,便于几何计算。
- 机台码(0.499刀具)坐标行顺序提取及正则健壮性提升。
- 移除强制编码指定,提升跨平台兼容性。
- 清理冗余测试代码,更新示例/测试钻带文件内容。
- 新增《必读.md》,明确AI开发不需编写测试单元。
本次无其他功能或逻辑变动的占位diff。
This commit is contained in:
2025-12-22 16:50:42 +08:00
parent 44de1cb982
commit 0eab0f42ee
13 changed files with 30955 additions and 10232 deletions

View File

@@ -0,0 +1,7 @@
# 必读.md
针对DrillTools项目的AI编程设计原则
## 指导原则
- 完成需求后不需要AI进行功能测试编写测试单元

View File

@@ -1,142 +0,0 @@
using System;
using System.Collections.Generic;
using DrillTools;
using DrillTools.Integration;
namespace DrillTools.Tests
{
/// <summary>
/// 坐标格式保留测试类
/// 用于验证修改后的代码能正确保留原始坐标格式
/// </summary>
public class CoordinateFormatTest
{
/// <summary>
/// 测试坐标格式保留功能
/// </summary>
public static void TestCoordinateFormatPreservation()
{
Console.WriteLine("=== 坐标格式保留测试 ===");
// 测试用例:各种格式的坐标
var testCases = new[]
{
"X-265000Y013250", // 负坐标,前导零
"X-265000Y008250", // 负坐标,前导零
"X075392Y559511", // 正坐标,前导零
"X017500Y519500G85X018500Y519500", // 槽孔坐标
"X-238500Y519500G85X-237500Y519500" // 负坐标槽孔
};
// 创建测试钻带内容
string drillTapeContent = CreateTestDrillTape(testCases);
// 解析钻带
var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
// 验证结果
if (result.Success)
{
Console.WriteLine("钻带解析成功!");
// 检查每个工具的坐标输出
foreach (var toolResult in result.ToolResults)
{
Console.WriteLine($"\n工具 T{toolResult.ToolNumber:D2} (直径: {toolResult.Diameter:F3}mm):");
Console.WriteLine($"坐标数量: {toolResult.Locations.Count}");
// 显示前5个坐标作为示例
int displayCount = Math.Min(5, toolResult.Locations.Count);
for (int i = 0; i < displayCount; i++)
{
string original = i < testCases.Length ? testCases[i] : "N/A";
string parsed = toolResult.Locations[i];
Console.WriteLine($" 原始: {original}");
Console.WriteLine($" 解析: {parsed}");
Console.WriteLine($" 匹配: {(original == parsed ? "" : "")}");
Console.WriteLine();
}
}
}
else
{
Console.WriteLine($"钻带解析失败: {result.Message}");
}
}
/// <summary>
/// 创建测试钻带内容
/// </summary>
private static string CreateTestDrillTape(string[] coordinates)
{
var drillTape = new System.Text.StringBuilder();
// 添加头部
drillTape.AppendLine("M48");
drillTape.AppendLine("METRIC");
drillTape.AppendLine("VER,1");
drillTape.AppendLine("FMAT,2");
// 添加刀具定义
drillTape.AppendLine("T01C1.000");
drillTape.AppendLine("T02C2.000");
// 添加结束标记
drillTape.AppendLine("%");
// 添加刀具1的坐标
drillTape.AppendLine("T01");
for (int i = 0; i < Math.Min(3, coordinates.Length); i++)
{
// 只添加普通坐标不含G85
if (!coordinates[i].Contains("G85"))
{
drillTape.AppendLine(coordinates[i]);
}
}
// 添加刀具2的坐标槽孔
drillTape.AppendLine("T02");
for (int i = 3; i < coordinates.Length; i++)
{
// 添加槽孔坐标含G85
if (coordinates[i].Contains("G85"))
{
drillTape.AppendLine(coordinates[i]);
}
}
// 添加结束标记
drillTape.AppendLine("M30");
return drillTape.ToString();
}
/// <summary>
/// 测试Point2D的原始字符串保留功能
/// </summary>
public static void TestPoint2DOriginalString()
{
Console.WriteLine("\n=== Point2D原始字符串测试 ===");
// 测试用例
var testCoordinates = new[]
{
"X-265000Y013250",
"X075392Y559511",
"X000123Y000456"
};
foreach (var coord in testCoordinates)
{
var point = Point2D.ParseFromDrillString(coord);
Console.WriteLine($"原始坐标: {coord}");
Console.WriteLine($"解析后X: {point.X:F3}, Y: {point.Y:F3}");
Console.WriteLine($"原始字符串: {point.OriginalString}");
Console.WriteLine($"字符串匹配: {(coord == point.OriginalString ? "" : "")}");
Console.WriteLine();
}
}
}
}

View File

@@ -37,6 +37,9 @@ namespace DrillTools.Integration
// 检查是否是机台码 (0.499孔径) // 检查是否是机台码 (0.499孔径)
bool isMachineCode = Math.Abs(tool.Diameter - 0.499) < 0.001; bool isMachineCode = Math.Abs(tool.Diameter - 0.499) < 0.001;
// 获取当前刀具的孔位数据
var toolHoles = holesByTool.ContainsKey(tool.Number) ? holesByTool[tool.Number] : new List<HoleInfo>();
// 根据刀具类型设置 // 根据刀具类型设置
ToolType toolType; ToolType toolType;
if (isMachineCode) if (isMachineCode)
@@ -45,17 +48,24 @@ namespace DrillTools.Integration
} }
else else
{ {
// 简化处理所有非机台码都设为Regular // 检查该刀具的孔位数据中是否包含G85槽孔
// 实际应用中可以根据需要判断是否为槽孔 bool hasSlotHoles = false;
toolType = ToolType.Regular;
foreach (var hole in toolHoles)
{
if (hole.Type == HoleType.Slot)
{
hasSlotHoles = true;
break;
}
}
toolType = hasSlotHoles ? ToolType.Slot : ToolType.Regular;
} }
// 计算刀具尾号类型和大类 // 计算刀具尾号类型和大类
var toolSuffixType = ToolItem.GetToolSuffixType(tool.Diameter); var toolSuffixType = ToolItem.GetToolSuffixType(tool.Diameter);
var ToolCategory = ToolItem.GetToolCategory(toolSuffixType); var ToolCategory = ToolItem.GetToolCategory(toolSuffixType);
// 获取当前刀具的孔位数据
var toolHoles = holesByTool.ContainsKey(tool.Number) ? holesByTool[tool.Number] : new List<HoleInfo>();
var locations = new List<string>(); var locations = new List<string>();
// 统计孔数并收集孔位坐标 // 统计孔数并收集孔位坐标
@@ -89,6 +99,7 @@ namespace DrillTools.Integration
else else
{ {
// 普通刀具和槽刀:正常处理 // 普通刀具和槽刀:正常处理
// 由于现在holes列表已经保持了原始顺序直接按顺序处理即可
foreach (var hole in toolHoles) foreach (var hole in toolHoles)
{ {
if (hole.Type == HoleType.Regular) if (hole.Type == HoleType.Regular)
@@ -124,7 +135,7 @@ namespace DrillTools.Integration
// 为机台码刀具提取机台码命令和类型 // 为机台码刀具提取机台码命令和类型
string machineCodeCommand = string.Empty; string machineCodeCommand = string.Empty;
string machineCodeType = string.Empty; string machineCodeType = string.Empty;
if (isMachineCode) if (isMachineCode)
{ {
// 从钻带内容中提取机台码信息 // 从钻带内容中提取机台码信息
@@ -143,7 +154,7 @@ namespace DrillTools.Integration
{ {
machineCodeCommand = machineCodeMatch.Groups[1].Value; // M97或M98 machineCodeCommand = machineCodeMatch.Groups[1].Value; // M97或M98
machineCodeType = machineCodeMatch.Groups[2].Value; // A*或B* machineCodeType = machineCodeMatch.Groups[2].Value; // A*或B*
// 添加日志验证机台码解析 // 添加日志验证机台码解析
System.Diagnostics.Debug.WriteLine($"[机台码解析] T{tool.Number:D2}: 命令={machineCodeCommand}, 类型={machineCodeType}"); System.Diagnostics.Debug.WriteLine($"[机台码解析] T{tool.Number:D2}: 命令={machineCodeCommand}, 类型={machineCodeType}");
} }
@@ -230,10 +241,13 @@ namespace DrillTools.Integration
var toolPattern = $@"%.+?T{tool.Number:D2}(.*?)(?=T\d{{2}}|M30)"; var toolPattern = $@"%.+?T{tool.Number:D2}(.*?)(?=T\d{{2}}|M30)";
var match = Regex.Match(drillTapeContent, toolPattern, RegexOptions.Singleline); var match = Regex.Match(drillTapeContent, toolPattern, RegexOptions.Singleline);
if (match.Success) if (match.Success)//机台码
{ {
string holeSection = match.Groups[1].Value; string holeSection = match.Groups[1].Value;
// 按行分割孔位数据,保持原始顺序
var lines = holeSection.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
// 查找机台码命令 // 查找机台码命令
var machineCodePattern = @"(M97|M98),(A\*|B\*),\$S \$N"; var machineCodePattern = @"(M97|M98),(A\*|B\*),\$S \$N";
var machineCodeMatch = Regex.Match(holeSection, machineCodePattern); var machineCodeMatch = Regex.Match(holeSection, machineCodePattern);
@@ -246,10 +260,6 @@ namespace DrillTools.Integration
// 根据机台码类型确定孔数 // 根据机台码类型确定孔数
int holeCount = (codeType == "A*") ? 57 : 58; int holeCount = (codeType == "A*") ? 57 : 58;
// 查找机台码坐标行
var coordinatePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
var coordinateMatches = Regex.Matches(holeSection, coordinatePattern);
// 添加机台码孔信息 // 添加机台码孔信息
for (int i = 0; i < holeCount; i++) for (int i = 0; i < holeCount; i++)
{ {
@@ -261,23 +271,33 @@ namespace DrillTools.Integration
}); });
} }
// 这样可以确保坐标数据被正确保存到 ToolResult.Locations 中 // 按原始顺序处理坐标行
foreach (Match coordMatch in coordinateMatches) foreach (var line in lines)
{ {
// 解析坐标 var trimmedLine = line.Trim();
double x = double.Parse(coordMatch.Groups[1].Value); if (string.IsNullOrEmpty(trimmedLine)) continue;
double y = double.Parse(coordMatch.Groups[2].Value);
// 保存原始坐标字符串 // 检查是否是坐标行
string originalCoordString = coordMatch.Value; var coordinatePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
var coordinateMatch = Regex.Match(trimmedLine, coordinatePattern);
// 添加一个特殊的孔位信息来保存实际坐标 if (coordinateMatch.Success)
holes.Add(new HoleInfo
{ {
ToolNumber = tool.Number, // 解析坐标
Type = HoleType.Regular, double x = double.Parse(coordinateMatch.Groups[1].Value);
Position = new Point2D(x, y, originalCoordString) double y = double.Parse(coordinateMatch.Groups[2].Value);
});
// 保存原始坐标字符串
string originalCoordString = coordinateMatch.Value;
// 添加一个特殊的孔位信息来保存实际坐标
holes.Add(new HoleInfo
{
ToolNumber = tool.Number,
Type = HoleType.Regular,
Position = new Point2D(x, y, originalCoordString)
});
}
} }
} }
} }
@@ -291,45 +311,48 @@ namespace DrillTools.Integration
if (match.Success) if (match.Success)
{ {
string holeSection = match.Groups[1].Value; string holeSection = match.Groups[1].Value;
// 先解析槽孔,并记录槽孔的起始坐标
var slotPattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)G85X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
var slotMatches = Regex.Matches(holeSection, slotPattern);
var slotStartPositions = new System.Collections.Generic.HashSet<string>();
foreach (Match slotMatch in slotMatches) // 按行分割孔位数据,保持原始顺序
var lines = holeSection.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{ {
var slot = SlotHoleCalculator.ParseLineSlotFromG85(slotMatch.Value, tool.Diameter); var trimmedLine = line.Trim();
holes.Add(new HoleInfo if (string.IsNullOrEmpty(trimmedLine)) continue;
{
ToolNumber = tool.Number, // 检查是否是槽孔G85指令
Type = HoleType.Slot, var slotPattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)G85X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
Slot = slot var slotMatch = Regex.Match(trimmedLine, slotPattern);
});
if (slotMatch.Success)
// 记录槽孔的起始坐标,以便后续排除
string startPos = $"X{slotMatch.Groups[1].Value}Y{slotMatch.Groups[2].Value}";
slotStartPositions.Add(startPos);
}
// 解析普通圆孔(排除槽孔的起始坐标)
var regularHolePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
var regularMatches = Regex.Matches(holeSection, regularHolePattern);
foreach (Match regularMatch in regularMatches)
{
// 排除槽孔的起始坐标
if (!slotStartPositions.Contains(regularMatch.Value))
{ {
// 处理槽孔
var slot = SlotHoleCalculator.ParseLineSlotFromG85(slotMatch.Value, tool.Diameter);
holes.Add(new HoleInfo holes.Add(new HoleInfo
{ {
ToolNumber = tool.Number, ToolNumber = tool.Number,
Type = HoleType.Regular, Type = HoleType.Slot,
Position = Point2D.ParseFromDrillString(regularMatch.Value) Slot = slot
}); });
} }
} else
{
// 检查是否是普通圆孔
var regularHolePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
var regularMatch = Regex.Match(trimmedLine, regularHolePattern);
// 解析槽孔(已在上面处理) if (regularMatch.Success)
{
// 处理普通圆孔
holes.Add(new HoleInfo
{
ToolNumber = tool.Number,
Type = HoleType.Regular,
Position = Point2D.ParseFromDrillString(regularMatch.Value)
});
}
}
}
} }
} }
} }
@@ -462,12 +485,12 @@ namespace DrillTools.Integration
public ToolType ToolType { get; set; } public ToolType ToolType { get; set; }
public ToolSuffixType ToolSuffixType { get; set; } public ToolSuffixType ToolSuffixType { get; set; }
public ToolCategory ToolCategory { get; set; } public ToolCategory ToolCategory { get; set; }
/// <summary> /// <summary>
/// 机台码命令 (M97或M98) /// 机台码命令 (M97或M98)
/// </summary> /// </summary>
public string MachineCodeCommand { get; set; } = string.Empty; public string MachineCodeCommand { get; set; } = string.Empty;
/// <summary> /// <summary>
/// 机台码类型 (A*或B*) /// 机台码类型 (A*或B*)
/// </summary> /// </summary>
@@ -604,6 +627,7 @@ namespace DrillTools.Integration
result.Add($"T{tool.ToolNumber:D2}"); result.Add($"T{tool.ToolNumber:D2}");
// 添加该刀具对应的所有坐标数据 // 添加该刀具对应的所有坐标数据
// HoleLocations现在应该已经保持了原始顺序
if (tool.ToolType != ToolType.MachineCode && tool.HoleLocations != null && tool.HoleLocations.Count > 0) if (tool.ToolType != ToolType.MachineCode && tool.HoleLocations != null && tool.HoleLocations.Count > 0)
{ {
foreach (var location in tool.HoleLocations) foreach (var location in tool.HoleLocations)
@@ -620,6 +644,7 @@ namespace DrillTools.Integration
result.Add($"{tool.MachineCodeCommand},{tool.MachineCodeType},$S $N"); result.Add($"{tool.MachineCodeCommand},{tool.MachineCodeType},$S $N");
// 添加机台码的坐标数据 // 添加机台码的坐标数据
// HoleLocations现在应该已经保持了原始顺序
if (tool.HoleLocations != null && tool.HoleLocations.Count > 0) if (tool.HoleLocations != null && tool.HoleLocations.Count > 0)
{ {
foreach (var location in tool.HoleLocations) foreach (var location in tool.HoleLocations)

View File

@@ -51,12 +51,19 @@
<!-- 主内容区域 --> <!-- 主内容区域 -->
<Grid Grid.Row="1"> <Grid Grid.Row="1">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" MinWidth="400" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="120" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- 刀具列表 --> <!-- 刀具列表 -->
<GroupBox Grid.Column="0" Header="刀具列表(可拖动排序)"> <GroupBox
Grid.RowSpan="2"
Grid.Column="0"
Header="刀具列表(可拖动排序)">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
@@ -142,8 +149,56 @@
</Grid> </Grid>
</GroupBox> </GroupBox>
<!-- 基础信息显示 -->
<GroupBox
Grid.Row="0"
Grid.Column="1"
Header="基础信息">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- 文件名单独一行 -->
<TextBlock
Grid.Row="0"
Text="{Binding FileNameWithoutExtension}"
VerticalAlignment="Center"
Margin="0,0,0,5"
FontWeight="Bold" />
<!-- 三个最小直径信息在同一行 -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<TextBlock Text="最小钻咀:" VerticalAlignment="Center" />
<TextBlock Text="{Binding MinDrillDiameter, StringFormat=F3}" VerticalAlignment="Center" Margin="5,0,0,0" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<TextBlock Text="最小槽刀:" VerticalAlignment="Center" />
<TextBlock Text="{Binding MinSlotDiameter, StringFormat=F3}" VerticalAlignment="Center" Margin="5,0,0,0" />
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<TextBlock Text="最小EA刀" VerticalAlignment="Center" />
<TextBlock Text="{Binding MinEADiameter, StringFormat=F3}" VerticalAlignment="Center" Margin="5,0,0,0" />
</StackPanel>
</Grid>
</Grid>
</GroupBox>
<!-- 钻带内容显示 --> <!-- 钻带内容显示 -->
<GroupBox Grid.Column="1" Header="钻带内容"> <GroupBox
Grid.Row="1"
Grid.Column="1"
Header="钻带内容">
<TextBox <TextBox
Name="DrillTapeTextBox" Name="DrillTapeTextBox"
HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"

View File

@@ -195,16 +195,6 @@ namespace DrillTools
// 保存原始文件路径 // 保存原始文件路径
ViewModel.OriginalFilePath = files[0]; ViewModel.OriginalFilePath = files[0];
Encoding ansiEncoding;
try
{
ansiEncoding = Encoding.GetEncoding(936); // 936是GB2312的代码页
}
catch
{
ansiEncoding = Encoding.Default; // 如果获取失败,使用系统默认编码
}
var process = new Process var process = new Process
{ {
StartInfo = new ProcessStartInfo StartInfo = new ProcessStartInfo
@@ -213,8 +203,7 @@ namespace DrillTools
Arguments = $"/c type \"{files[0]}\"", Arguments = $"/c type \"{files[0]}\"",
RedirectStandardOutput = true, RedirectStandardOutput = true,
UseShellExecute = false, UseShellExecute = false,
CreateNoWindow = true, CreateNoWindow = true
StandardOutputEncoding = ansiEncoding
} }
}; };

View File

@@ -26,6 +26,10 @@ namespace DrillTools
private bool _canMoveDown; private bool _canMoveDown;
private string _originalFilePath = string.Empty; private string _originalFilePath = string.Empty;
private bool _isTopmost = true; // 默认置顶 private bool _isTopmost = true; // 默认置顶
private string _fileNameWithoutExtension = string.Empty;
private double _minDrillDiameter;
private double _minSlotDiameter;
private double _minEADiameter;
/// <summary> /// <summary>
/// 刀具列表 /// 刀具列表
@@ -90,6 +94,16 @@ namespace DrillTools
{ {
// 当原始文件路径改变时,通知 HasOriginalFile 属性也已更改 // 当原始文件路径改变时,通知 HasOriginalFile 属性也已更改
OnPropertyChanged(nameof(HasOriginalFile)); OnPropertyChanged(nameof(HasOriginalFile));
// 更新文件名(不包含后缀)
if (!string.IsNullOrEmpty(value))
{
FileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(value);
}
else
{
FileNameWithoutExtension = string.Empty;
}
} }
} }
} }
@@ -129,6 +143,42 @@ namespace DrillTools
/// </summary> /// </summary>
public string TopmostButtonText => IsTopmost ? "取消置顶" : "窗口置顶"; public string TopmostButtonText => IsTopmost ? "取消置顶" : "窗口置顶";
/// <summary>
/// 文件名(不包含后缀)
/// </summary>
public string FileNameWithoutExtension
{
get => _fileNameWithoutExtension;
set => SetProperty(ref _fileNameWithoutExtension, value);
}
/// <summary>
/// 最小钻咀直径
/// </summary>
public double MinDrillDiameter
{
get => _minDrillDiameter;
set => SetProperty(ref _minDrillDiameter, value);
}
/// <summary>
/// 最小槽刀直径
/// </summary>
public double MinSlotDiameter
{
get => _minSlotDiameter;
set => SetProperty(ref _minSlotDiameter, value);
}
/// <summary>
/// 最小EA刀直径
/// </summary>
public double MinEADiameter
{
get => _minEADiameter;
set => SetProperty(ref _minEADiameter, value);
}
/// <summary> /// <summary>
/// 从钻带内容加载刀具信息 /// 从钻带内容加载刀具信息
/// </summary> /// </summary>
@@ -182,15 +232,26 @@ namespace DrillTools
if (match.Success) if (match.Success)
{ {
string holeSection = match.Groups[1].Value; string holeSection = match.Groups[1].Value;
// 查找机台码坐标行 // 按行分割孔位数据,保持原始顺序
var coordinatePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)"; var lines = holeSection.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
var coordinateMatches = System.Text.RegularExpressions.Regex.Matches(holeSection, coordinatePattern);
toolItem.HoleLocations = new List<string>(); toolItem.HoleLocations = new List<string>();
foreach (Match coordMatch in coordinateMatches)
// 按原始顺序处理坐标行
foreach (var line in lines)
{ {
toolItem.HoleLocations.Add(coordMatch.Value); var trimmedLine = line.Trim();
if (string.IsNullOrEmpty(trimmedLine)) continue;
// 检查是否是坐标行
var coordinatePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
var coordinateMatch = System.Text.RegularExpressions.Regex.Match(trimmedLine, coordinatePattern);
if (coordinateMatch.Success)
{
toolItem.HoleLocations.Add(coordinateMatch.Value);
}
} }
System.Diagnostics.Debug.WriteLine($"[机台码坐标] T{toolResult.ToolNumber:D2}: 找到{toolItem.HoleLocations.Count}个坐标"); System.Diagnostics.Debug.WriteLine($"[机台码坐标] T{toolResult.ToolNumber:D2}: 找到{toolItem.HoleLocations.Count}个坐标");
@@ -218,6 +279,9 @@ namespace DrillTools
// 更新按钮状态 // 更新按钮状态
UpdateMoveButtonsState(); UpdateMoveButtonsState();
// 计算并更新最小直径信息
UpdateMinDiameterInfo();
// 检查并应用-sort.txt文件中的刀具排序 // 检查并应用-sort.txt文件中的刀具排序
if (!string.IsNullOrEmpty(OriginalFilePath)) if (!string.IsNullOrEmpty(OriginalFilePath))
{ {
@@ -683,6 +747,7 @@ namespace DrillTools
result.Add($"T{tool.ToolNumber:D2}"); result.Add($"T{tool.ToolNumber:D2}");
// 添加该刀具对应的所有坐标数据 // 添加该刀具对应的所有坐标数据
// HoleLocations现在应该已经保持了原始顺序
if (tool.ToolType != ToolType.MachineCode && tool.HoleLocations != null && tool.HoleLocations.Count > 0) if (tool.ToolType != ToolType.MachineCode && tool.HoleLocations != null && tool.HoleLocations.Count > 0)
{ {
foreach (var location in tool.HoleLocations) foreach (var location in tool.HoleLocations)
@@ -699,6 +764,7 @@ namespace DrillTools
result.Add($"{tool.MachineCodeCommand},{tool.MachineCodeType},$S $N"); result.Add($"{tool.MachineCodeCommand},{tool.MachineCodeType},$S $N");
// 添加机台码的坐标数据 // 添加机台码的坐标数据
// HoleLocations现在应该已经保持了原始顺序
if (tool.HoleLocations != null && tool.HoleLocations.Count > 0) if (tool.HoleLocations != null && tool.HoleLocations.Count > 0)
{ {
foreach (var location in tool.HoleLocations) foreach (var location in tool.HoleLocations)
@@ -866,6 +932,9 @@ namespace DrillTools
// 更新按钮状态 // 更新按钮状态
UpdateMoveButtonsState(); UpdateMoveButtonsState();
// 计算并更新最小直径信息
UpdateMinDiameterInfo();
// 加载示例钻带内容 // 加载示例钻带内容
DrillTapeContent = @"M48 DrillTapeContent = @"M48
@@ -1342,5 +1411,48 @@ M30";
{ {
IsTopmost = !IsTopmost; IsTopmost = !IsTopmost;
} }
/// <summary>
/// 更新最小直径信息
/// </summary>
private void UpdateMinDiameterInfo()
{
// 初始化为最大值,以便找到最小值
MinDrillDiameter = double.MaxValue;
MinSlotDiameter = double.MaxValue;
MinEADiameter = double.MaxValue;
foreach (var tool in Tools)
{
// 根据刀具类型分类计算最小直径
if (tool.ToolType == ToolType.Regular)
{
// 普通钻咀
if (tool.Diameter < MinDrillDiameter)
MinDrillDiameter = tool.Diameter;
}
else if (tool.ToolType == ToolType.Slot)
{
// 槽刀
if (tool.Diameter < MinSlotDiameter)
MinSlotDiameter = tool.Diameter;
// 检查是否是EA型槽刀尾号为2或6
if ((tool.ToolSuffixType == ToolSuffixType.EASlot || tool.ToolSuffixType == ToolSuffixType.EASlot2)
&& tool.Diameter < MinEADiameter)
MinEADiameter = tool.Diameter;
}
}
// 如果没有找到对应的刀具类型将值设为0
if (MinDrillDiameter == double.MaxValue)
MinDrillDiameter = 0;
if (MinSlotDiameter == double.MaxValue)
MinSlotDiameter = 0;
if (MinEADiameter == double.MaxValue)
MinEADiameter = 0;
}
} }
} }

View File

@@ -12,21 +12,21 @@ namespace DrillTools
public double X { get; set; } public double X { get; set; }
public double Y { get; set; } public double Y { get; set; }
public string OriginalString { get; set; } // 存储原始坐标字符串 public string OriginalString { get; set; } // 存储原始坐标字符串
public Point2D(double x, double y) public Point2D(double x, double y)
{ {
X = x; X = x;
Y = y; Y = y;
OriginalString = ""; OriginalString = "";
} }
public Point2D(double x, double y, string originalString) public Point2D(double x, double y, string originalString)
{ {
X = x; X = x;
Y = y; Y = y;
OriginalString = originalString; OriginalString = originalString;
} }
/// <summary> /// <summary>
/// 从钻带坐标字符串创建点格式X+/-数字Y+/-数字) /// 从钻带坐标字符串创建点格式X+/-数字Y+/-数字)
/// </summary> /// </summary>
@@ -42,8 +42,9 @@ namespace DrillTools
} }
throw new ArgumentException($"无效的钻带坐标格式: {drillString}"); throw new ArgumentException($"无效的钻带坐标格式: {drillString}");
} }
public static Point2D operator +(Point2D p1, Point2D p2) => new Point2D(p1.X + p2.X, p1.Y + p2.Y); public static Point2D operator +(Point2D p1, Point2D p2) => new Point2D(p1.X + p2.X, p1.Y + p2.Y);
public static Point2D operator -(Point2D p1, Point2D p2) => new Point2D(p1.X - p2.X, p1.Y - p2.Y); public static Point2D operator -(Point2D p1, Point2D p2) => new Point2D(p1.X - p2.X, p1.Y - p2.Y);
} }
@@ -55,14 +56,14 @@ namespace DrillTools
public Point2D StartPoint { get; set; } public Point2D StartPoint { get; set; }
public Point2D EndPoint { get; set; } public Point2D EndPoint { get; set; }
public double Width { get; set; } // 槽孔宽度/孔径单位mm public double Width { get; set; } // 槽孔宽度/孔径单位mm
public LineSlot(Point2D startPoint, Point2D endPoint, double width) public LineSlot(Point2D startPoint, Point2D endPoint, double width)
{ {
StartPoint = startPoint; StartPoint = startPoint;
EndPoint = endPoint; EndPoint = endPoint;
Width = width; Width = width;
} }
/// <summary> /// <summary>
/// 获取槽孔长度 /// 获取槽孔长度
/// </summary> /// </summary>
@@ -79,7 +80,7 @@ namespace DrillTools
public Point2D CenterPoint { get; set; } public Point2D CenterPoint { get; set; }
public double Width { get; set; } // 槽孔宽度/孔径单位mm public double Width { get; set; } // 槽孔宽度/孔径单位mm
public bool CounterClockwise { get; set; } // 是否逆时针方向 public bool CounterClockwise { get; set; } // 是否逆时针方向
public ArcSlot(Point2D startPoint, Point2D endPoint, Point2D centerPoint, double width, bool counterClockwise = false) public ArcSlot(Point2D startPoint, Point2D endPoint, Point2D centerPoint, double width, bool counterClockwise = false)
{ {
StartPoint = startPoint; StartPoint = startPoint;
@@ -88,7 +89,7 @@ namespace DrillTools
Width = width; Width = width;
CounterClockwise = counterClockwise; CounterClockwise = counterClockwise;
} }
/// <summary> /// <summary>
/// 获取弧段半径 /// 获取弧段半径
/// </summary> /// </summary>
@@ -105,7 +106,7 @@ namespace DrillTools
/// 默认凸位高度值CAM350标准单位mm /// 默认凸位高度值CAM350标准单位mm
/// </summary> /// </summary>
private const double DEFAULT_TOLERANCE = 0.0127; private const double DEFAULT_TOLERANCE = 0.0127;
/// <summary> /// <summary>
/// 计算线段槽孔的钻孔数量 /// 计算线段槽孔的钻孔数量
/// </summary> /// </summary>
@@ -116,19 +117,19 @@ namespace DrillTools
{ {
// 计算孔半径 // 计算孔半径
double radius = slot.Width / 2.0; double radius = slot.Width / 2.0;
// 计算槽孔长度 // 计算槽孔长度
double slotLength = slot.Length; double slotLength = slot.Length;
// 计算孔中心距 // 计算孔中心距
double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance); double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance);
// 计算孔数 // 计算孔数
int holeCount = (int)Math.Abs(Math.Floor(-slotLength / holeCenterDistance)) + 1; int holeCount = (int)Math.Abs(Math.Floor(-slotLength / holeCenterDistance)) + 1;
return holeCount; return holeCount;
} }
/// <summary> /// <summary>
/// 计算弧段槽孔的钻孔数量 /// 计算弧段槽孔的钻孔数量
/// </summary> /// </summary>
@@ -139,19 +140,19 @@ namespace DrillTools
{ {
// 计算孔半径 // 计算孔半径
double radius = slot.Width / 2.0; double radius = slot.Width / 2.0;
// 计算弧段长度 // 计算弧段长度
double arcLength = CalculateArcLength(slot); double arcLength = CalculateArcLength(slot);
// 计算孔中心距 // 计算孔中心距
double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance); double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance);
// 计算孔数 // 计算孔数
int holeCount = (int)Math.Abs(Math.Floor(-arcLength / holeCenterDistance)) + 1; int holeCount = (int)Math.Abs(Math.Floor(-arcLength / holeCenterDistance)) + 1;
return holeCount; return holeCount;
} }
/// <summary> /// <summary>
/// 计算线段槽孔的钻孔位置 /// 计算线段槽孔的钻孔位置
/// </summary> /// </summary>
@@ -161,47 +162,47 @@ namespace DrillTools
public static List<Point2D> CalculateLineSlotHolePositions(LineSlot slot, double tolerance = DEFAULT_TOLERANCE) public static List<Point2D> CalculateLineSlotHolePositions(LineSlot slot, double tolerance = DEFAULT_TOLERANCE)
{ {
List<Point2D> positions = new List<Point2D>(); List<Point2D> positions = new List<Point2D>();
// 计算孔半径 // 计算孔半径
double radius = slot.Width / 2.0; double radius = slot.Width / 2.0;
// 计算孔中心距 // 计算孔中心距
double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance); double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance);
// 计算槽孔长度 // 计算槽孔长度
double slotLength = slot.Length; double slotLength = slot.Length;
// 计算孔数 // 计算孔数
int holeCount = CalculateLineSlotHoleCount(slot, tolerance); int holeCount = CalculateLineSlotHoleCount(slot, tolerance);
// 计算方位角 // 计算方位角
double angle = CalculateAngle(slot.StartPoint, slot.EndPoint); double angle = CalculateAngle(slot.StartPoint, slot.EndPoint);
// 添加起点 // 添加起点
positions.Add(slot.StartPoint); positions.Add(slot.StartPoint);
// 计算中间点 // 计算中间点
if (holeCount > 2) if (holeCount > 2)
{ {
double avgDistance = slotLength / (holeCount - 1); double avgDistance = slotLength / (holeCount - 1);
Point2D currentPoint = slot.StartPoint; Point2D currentPoint = slot.StartPoint;
for (int i = 1; i < holeCount - 1; i++) for (int i = 1; i < holeCount - 1; i++)
{ {
currentPoint = CalculateNextPoint(currentPoint, avgDistance, angle); currentPoint = CalculateNextPoint(currentPoint, avgDistance, angle);
positions.Add(currentPoint); positions.Add(currentPoint);
} }
} }
// 添加终点 // 添加终点
if (holeCount > 1) if (holeCount > 1)
{ {
positions.Add(slot.EndPoint); positions.Add(slot.EndPoint);
} }
return positions; return positions;
} }
/// <summary> /// <summary>
/// 计算弧段槽孔的钻孔位置 /// 计算弧段槽孔的钻孔位置
/// </summary> /// </summary>
@@ -211,31 +212,31 @@ namespace DrillTools
public static List<Point2D> CalculateArcSlotHolePositions(ArcSlot slot, double tolerance = DEFAULT_TOLERANCE) public static List<Point2D> CalculateArcSlotHolePositions(ArcSlot slot, double tolerance = DEFAULT_TOLERANCE)
{ {
List<Point2D> positions = new List<Point2D>(); List<Point2D> positions = new List<Point2D>();
// 计算孔半径 // 计算孔半径
double radius = slot.Width / 2.0; double radius = slot.Width / 2.0;
// 计算孔中心距 // 计算孔中心距
double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance); double holeCenterDistance = CalculateHoleCenterDistance(radius, tolerance);
// 计算弧段半径 // 计算弧段半径
double arcRadius = slot.Radius; double arcRadius = slot.Radius;
// 计算弧段圆心角 // 计算弧段圆心角
double arcAngle = CalculateArcAngle(slot); double arcAngle = CalculateArcAngle(slot);
// 计算孔数 // 计算孔数
int holeCount = CalculateArcSlotHoleCount(slot, tolerance); int holeCount = CalculateArcSlotHoleCount(slot, tolerance);
// 计算角度步长 // 计算角度步长
double angleStep = arcAngle / (holeCount - 1); double angleStep = arcAngle / (holeCount - 1);
// 计算起始角度 // 计算起始角度
double startAngle = CalculateAngle(slot.CenterPoint, slot.StartPoint); double startAngle = CalculateAngle(slot.CenterPoint, slot.StartPoint);
// 添加起点 // 添加起点
positions.Add(slot.StartPoint); positions.Add(slot.StartPoint);
// 计算中间点 // 计算中间点
if (holeCount > 2) if (holeCount > 2)
{ {
@@ -248,12 +249,12 @@ namespace DrillTools
{ {
currentAngle += angleStep; currentAngle += angleStep;
} }
for (int i = 1; i < holeCount - 1; i++) for (int i = 1; i < holeCount - 1; i++)
{ {
Point2D point = CalculatePointOnArc(slot.CenterPoint, arcRadius, currentAngle); Point2D point = CalculatePointOnArc(slot.CenterPoint, arcRadius, currentAngle);
positions.Add(point); positions.Add(point);
if (slot.CounterClockwise) if (slot.CounterClockwise)
{ {
currentAngle -= angleStep; currentAngle -= angleStep;
@@ -264,16 +265,16 @@ namespace DrillTools
} }
} }
} }
// 添加终点 // 添加终点
if (holeCount > 1) if (holeCount > 1)
{ {
positions.Add(slot.EndPoint); positions.Add(slot.EndPoint);
} }
return positions; return positions;
} }
/// <summary> /// <summary>
/// 从钻带G85命令解析线段槽孔 /// 从钻带G85命令解析线段槽孔
/// </summary> /// </summary>
@@ -291,7 +292,7 @@ namespace DrillTools
string startY = match.Groups[2].Value; string startY = match.Groups[2].Value;
string endX = match.Groups[3].Value; string endX = match.Groups[3].Value;
string endY = match.Groups[4].Value; string endY = match.Groups[4].Value;
Point2D startPoint = new Point2D( Point2D startPoint = new Point2D(
double.Parse(startX) / 1000.0, double.Parse(startX) / 1000.0,
double.Parse(startY) / 1000.0, double.Parse(startY) / 1000.0,
@@ -302,14 +303,14 @@ namespace DrillTools
double.Parse(endY) / 1000.0, double.Parse(endY) / 1000.0,
$"X{endX}Y{endY}" $"X{endX}Y{endY}"
); );
return new LineSlot(startPoint, endPoint, width); return new LineSlot(startPoint, endPoint, width);
} }
throw new ArgumentException($"无效的G85命令格式: {g85Command}"); throw new ArgumentException($"无效的G85命令格式: {g85Command}");
} }
// 辅助方法 // 辅助方法
/// <summary> /// <summary>
/// 计算两点间欧氏距离 /// 计算两点间欧氏距离
/// </summary> /// </summary>
@@ -317,7 +318,7 @@ namespace DrillTools
{ {
return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2)); return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
} }
/// <summary> /// <summary>
/// 计算方位角(度数) /// 计算方位角(度数)
/// </summary> /// </summary>
@@ -325,14 +326,14 @@ namespace DrillTools
{ {
double angleRad = Math.Atan2(endPoint.Y - startPoint.Y, endPoint.X - startPoint.X); double angleRad = Math.Atan2(endPoint.Y - startPoint.Y, endPoint.X - startPoint.X);
double angleDeg = angleRad * 180.0 / Math.PI; double angleDeg = angleRad * 180.0 / Math.PI;
// 转换为0-360度范围 // 转换为0-360度范围
if (angleDeg < 0) if (angleDeg < 0)
angleDeg += 360; angleDeg += 360;
return angleDeg; return angleDeg;
} }
/// <summary> /// <summary>
/// 计算弧段长度 /// 计算弧段长度
/// </summary> /// </summary>
@@ -343,7 +344,7 @@ namespace DrillTools
double angleRad = angleDeg * Math.PI / 180.0; double angleRad = angleDeg * Math.PI / 180.0;
return radius * angleRad; return radius * angleRad;
} }
/// <summary> /// <summary>
/// 计算弧段圆心角(度数) /// 计算弧段圆心角(度数)
/// </summary> /// </summary>
@@ -351,7 +352,7 @@ namespace DrillTools
{ {
double startAngle = CalculateAngle(arc.CenterPoint, arc.StartPoint); double startAngle = CalculateAngle(arc.CenterPoint, arc.StartPoint);
double endAngle = CalculateAngle(arc.CenterPoint, arc.EndPoint); double endAngle = CalculateAngle(arc.CenterPoint, arc.EndPoint);
double angleSum; double angleSum;
if (arc.CounterClockwise) if (arc.CounterClockwise)
{ {
@@ -367,10 +368,10 @@ namespace DrillTools
else else
angleSum = Math.Abs(startAngle - endAngle); angleSum = Math.Abs(startAngle - endAngle);
} }
return angleSum; return angleSum;
} }
/// <summary> /// <summary>
/// 计算孔中心距 /// 计算孔中心距
/// </summary> /// </summary>
@@ -378,7 +379,7 @@ namespace DrillTools
{ {
return Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(radius - tolerance, 2)) * 2; return Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(radius - tolerance, 2)) * 2;
} }
/// <summary> /// <summary>
/// 根据起点、距离和角度计算下一个点 /// 根据起点、距离和角度计算下一个点
/// </summary> /// </summary>
@@ -390,7 +391,7 @@ namespace DrillTools
startPoint.Y + distance * Math.Sin(angleRad) startPoint.Y + distance * Math.Sin(angleRad)
); );
} }
/// <summary> /// <summary>
/// 根据圆心、半径和角度计算圆弧上的点 /// 根据圆心、半径和角度计算圆弧上的点
/// </summary> /// </summary>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +0,0 @@
M48
T01C3.050
T02C1.900
%
T01
X-154500Y549000
X154500Y562000
X154500Y038000
X-154500Y038000
T02
X045112Y593500
M30

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff