feat: 增加钻带涨缩功能,支持倍率/PPM模式缩放坐标
- 新增 ExcellonScaler 引擎:普通孔缩放坐标,G85槽孔保护槽长,刀具定义行原样保留 - 新增 DrillScalingWindow 参数设置窗口:倍率/PPM模式切换,X/Y独立输入 - 集成到启动功能菜单:.dr2/.dpin 文件显示"涨缩"按钮 - 输出覆盖原文件 + .bak 备份,GB2312 编码
This commit is contained in:
43
App.xaml.cs
43
App.xaml.cs
@@ -48,6 +48,8 @@ namespace DrillTools
|
|||||||
|
|
||||||
bool canClearParameters = DrillTapeParameterCleaner.CanClearParameters(content);
|
bool canClearParameters = DrillTapeParameterCleaner.CanClearParameters(content);
|
||||||
bool canGeneratePpDrillTape = viewModel.CanGeneratePpDrillTape;
|
bool canGeneratePpDrillTape = viewModel.CanGeneratePpDrillTape;
|
||||||
|
string extension = Path.GetExtension(filePath).ToLowerInvariant();
|
||||||
|
bool canScaleDrillTape = extension == ".dr2" || extension == ".dpin";
|
||||||
double minDrill = viewModel.MinDrillDiameter;
|
double minDrill = viewModel.MinDrillDiameter;
|
||||||
double minSlot = viewModel.MinSlotDiameter;
|
double minSlot = viewModel.MinSlotDiameter;
|
||||||
double minEA = viewModel.MinEADiameter;
|
double minEA = viewModel.MinEADiameter;
|
||||||
@@ -62,6 +64,7 @@ namespace DrillTools
|
|||||||
filePath,
|
filePath,
|
||||||
canClearParameters,
|
canClearParameters,
|
||||||
canGeneratePpDrillTape,
|
canGeneratePpDrillTape,
|
||||||
|
canScaleDrillTape,
|
||||||
minDrill,
|
minDrill,
|
||||||
minSlot,
|
minSlot,
|
||||||
minEA,
|
minEA,
|
||||||
@@ -91,6 +94,10 @@ namespace DrillTools
|
|||||||
PerformPpDrillTapeGeneration(filePath);
|
PerformPpDrillTapeGeneration(filePath);
|
||||||
Shutdown();
|
Shutdown();
|
||||||
break;
|
break;
|
||||||
|
case StartupAction.ScaleDrillTape:
|
||||||
|
PerformDrillScaling(filePath);
|
||||||
|
Shutdown();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Shutdown();
|
Shutdown();
|
||||||
break;
|
break;
|
||||||
@@ -191,6 +198,42 @@ namespace DrillTools
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PerformDrillScaling(string filePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var scalingWindow = new DrillScalingWindow();
|
||||||
|
scalingWindow.ShowDialog();
|
||||||
|
|
||||||
|
if (scalingWindow.ScalingResult == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var (kx, ky) = scalingWindow.ScalingResult.Value;
|
||||||
|
|
||||||
|
string content = CommandTypeFileReader.ReadAllText(filePath);
|
||||||
|
string scaledContent = Integration.ExcellonScaler.Scale(content, kx, ky);
|
||||||
|
|
||||||
|
// 备份原文件
|
||||||
|
string backupFilePath = filePath + ".bak";
|
||||||
|
File.Copy(filePath, backupFilePath, true);
|
||||||
|
|
||||||
|
// 写入缩放后的内容
|
||||||
|
using var writer = new StreamWriter(filePath, false, Encoding.GetEncoding(936));
|
||||||
|
writer.Write(scaledContent);
|
||||||
|
|
||||||
|
System.Windows.MessageBox.Show(
|
||||||
|
$"涨缩完成,原文件已备份为:\n{Path.GetFileName(filePath)}.bak",
|
||||||
|
"涨缩完成",
|
||||||
|
MessageBoxButton.OK,
|
||||||
|
MessageBoxImage.Information);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Windows.MessageBox.Show($"涨缩失败:\n{ex.Message}",
|
||||||
|
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void RegisterShellContextMenu()
|
private static void RegisterShellContextMenu()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
145
DrillScalingViewModel.cs
Normal file
145
DrillScalingViewModel.cs
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace DrillTools
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 涨缩参数输入模式
|
||||||
|
/// </summary>
|
||||||
|
public enum ScalingMode
|
||||||
|
{
|
||||||
|
/// <summary>倍率模式</summary>
|
||||||
|
Ratio,
|
||||||
|
/// <summary>PPM 模式</summary>
|
||||||
|
Ppm
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 钻带涨缩窗口视图模型
|
||||||
|
/// </summary>
|
||||||
|
public class DrillScalingViewModel : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
private ScalingMode _mode = ScalingMode.Ratio;
|
||||||
|
private string _inputX = "1.0";
|
||||||
|
private string _inputY = "1.0";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缩放模式(倍率 / PPM)
|
||||||
|
/// </summary>
|
||||||
|
public ScalingMode Mode
|
||||||
|
{
|
||||||
|
get => _mode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _mode, value))
|
||||||
|
{
|
||||||
|
OnPropertyChanged(nameof(ModeLabelX));
|
||||||
|
OnPropertyChanged(nameof(ModeLabelY));
|
||||||
|
OnPropertyChanged(nameof(ModeDescription));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// X 方向输入值(原始字符串)
|
||||||
|
/// </summary>
|
||||||
|
public string InputX
|
||||||
|
{
|
||||||
|
get => _inputX;
|
||||||
|
set => SetProperty(ref _inputX, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Y 方向输入值(原始字符串)
|
||||||
|
/// </summary>
|
||||||
|
public string InputY
|
||||||
|
{
|
||||||
|
get => _inputY;
|
||||||
|
set => SetProperty(ref _inputY, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// X 方向标签文本(根据模式变化)
|
||||||
|
/// </summary>
|
||||||
|
public string ModeLabelX => Mode == ScalingMode.Ratio ? "倍率 X" : "PPM X";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Y 方向标签文本(根据模式变化)
|
||||||
|
/// </summary>
|
||||||
|
public string ModeLabelY => Mode == ScalingMode.Ratio ? "倍率 Y" : "PPM Y";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模式说明文本
|
||||||
|
/// </summary>
|
||||||
|
public string ModeDescription => Mode == ScalingMode.Ratio
|
||||||
|
? "倍率模式:直接输入缩放倍率(如 1.0005)"
|
||||||
|
: "PPM 模式:输入百万分率(如 500 表示 +500ppm)";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算后的 X 方向实际缩放倍率
|
||||||
|
/// </summary>
|
||||||
|
public double Kx
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!double.TryParse(_inputX, out double value))
|
||||||
|
return 1.0;
|
||||||
|
return Mode == ScalingMode.Ratio ? value : 1.0 + value / 1e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算后的 Y 方向实际缩放倍率
|
||||||
|
/// </summary>
|
||||||
|
public double Ky
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!double.TryParse(_inputY, out double value))
|
||||||
|
return 1.0;
|
||||||
|
return Mode == ScalingMode.Ratio ? value : 1.0 + value / 1e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证输入是否有效
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>验证结果,null 表示有效,非 null 为错误消息</returns>
|
||||||
|
public string? Validate()
|
||||||
|
{
|
||||||
|
if (!double.TryParse(_inputX, out double xVal))
|
||||||
|
return "X 值不是有效的数字";
|
||||||
|
if (!double.TryParse(_inputY, out double yVal))
|
||||||
|
return "Y 值不是有效的数字";
|
||||||
|
|
||||||
|
if (Mode == ScalingMode.Ratio)
|
||||||
|
{
|
||||||
|
if (xVal <= 0)
|
||||||
|
return "倍率 X 必须大于 0";
|
||||||
|
if (yVal <= 0)
|
||||||
|
return "倍率 Y 必须大于 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
|
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
|
||||||
|
{
|
||||||
|
if (EqualityComparer<T>.Default.Equals(field, value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
field = value;
|
||||||
|
OnPropertyChanged(propertyName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
94
DrillScalingWindow.xaml
Normal file
94
DrillScalingWindow.xaml
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<Window x:Class="DrillTools.DrillScalingWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="钻带涨缩"
|
||||||
|
Width="350"
|
||||||
|
SizeToContent="Height"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
Topmost="True"
|
||||||
|
WindowStartupLocation="CenterScreen">
|
||||||
|
<Grid Margin="15">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- 模式选择 -->
|
||||||
|
<GroupBox Grid.Row="0" Header="输入模式" Margin="0,0,0,10">
|
||||||
|
<StackPanel>
|
||||||
|
<RadioButton Name="RatioRadioButton"
|
||||||
|
Content="倍率模式"
|
||||||
|
IsChecked="True"
|
||||||
|
Margin="0,5,0,5"
|
||||||
|
Checked="ModeRadioButton_Changed" />
|
||||||
|
<RadioButton Name="PpmRadioButton"
|
||||||
|
Content="PPM 模式"
|
||||||
|
Margin="0,0,0,5"
|
||||||
|
Checked="ModeRadioButton_Changed" />
|
||||||
|
<TextBlock Text="{Binding ModeDescription}"
|
||||||
|
Foreground="Gray"
|
||||||
|
FontSize="11"
|
||||||
|
Margin="20,0,0,5" />
|
||||||
|
</StackPanel>
|
||||||
|
</GroupBox>
|
||||||
|
|
||||||
|
<!-- X 方向参数 -->
|
||||||
|
<Grid Grid.Row="1" Margin="0,0,0,8">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Grid.Column="0"
|
||||||
|
Text="{Binding ModeLabelX}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0,0,10,0" />
|
||||||
|
<TextBox Grid.Column="1"
|
||||||
|
Text="{Binding InputX, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
Height="25" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Y 方向参数 -->
|
||||||
|
<Grid Grid.Row="2" Margin="0,0,0,8">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Grid.Column="0"
|
||||||
|
Text="{Binding ModeLabelY}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0,0,10,0" />
|
||||||
|
<TextBox Grid.Column="1"
|
||||||
|
Text="{Binding InputY, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
Height="25" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- 提示信息 -->
|
||||||
|
<TextBlock Grid.Row="3"
|
||||||
|
Name="ErrorText"
|
||||||
|
Foreground="Red"
|
||||||
|
FontSize="11"
|
||||||
|
Text=""
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Visibility="Collapsed" />
|
||||||
|
|
||||||
|
<!-- 按钮区域 -->
|
||||||
|
<StackPanel Grid.Row="4"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<Button Width="80"
|
||||||
|
Height="30"
|
||||||
|
Content="取消"
|
||||||
|
IsCancel="True"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Click="CancelButton_Click" />
|
||||||
|
<Button Width="80"
|
||||||
|
Height="30"
|
||||||
|
Content="执行"
|
||||||
|
IsDefault="True"
|
||||||
|
Click="ExecuteButton_Click" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
57
DrillScalingWindow.xaml.cs
Normal file
57
DrillScalingWindow.xaml.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace DrillTools
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 钻带涨缩参数设置窗口
|
||||||
|
/// </summary>
|
||||||
|
public partial class DrillScalingWindow : Window
|
||||||
|
{
|
||||||
|
private readonly DrillScalingViewModel _viewModel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户确认后的缩放结果(kx, ky)
|
||||||
|
/// </summary>
|
||||||
|
public (double Kx, double Ky)? ScalingResult { get; private set; }
|
||||||
|
|
||||||
|
public DrillScalingWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
_viewModel = new DrillScalingViewModel();
|
||||||
|
DataContext = _viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ModeRadioButton_Changed(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_viewModel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (RatioRadioButton.IsChecked == true)
|
||||||
|
_viewModel.Mode = ScalingMode.Ratio;
|
||||||
|
else if (PpmRadioButton.IsChecked == true)
|
||||||
|
_viewModel.Mode = ScalingMode.Ppm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecuteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var error = _viewModel.Validate();
|
||||||
|
if (error != null)
|
||||||
|
{
|
||||||
|
ErrorText.Text = error;
|
||||||
|
ErrorText.Visibility = Visibility.Visible;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScalingResult = (_viewModel.Kx, _viewModel.Ky);
|
||||||
|
DialogResult = true;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ScalingResult = null;
|
||||||
|
DialogResult = false;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
154
ExcellonScaler.cs
Normal file
154
ExcellonScaler.cs
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace DrillTools.Integration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Excellon 钻带涨缩引擎
|
||||||
|
/// 对钻孔坐标进行 X/Y 方向独立缩放,保持槽孔长度不变
|
||||||
|
/// </summary>
|
||||||
|
internal static class ExcellonScaler
|
||||||
|
{
|
||||||
|
// 坐标模式:X 后跟可选符号的数字(可能含小数点),Y 同理
|
||||||
|
private static readonly Regex CoordinatePattern = new(
|
||||||
|
@"^X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)$",
|
||||||
|
RegexOptions.Compiled);
|
||||||
|
|
||||||
|
// G85 槽孔模式:X...Y...G85X...Y...
|
||||||
|
private static readonly Regex SlotPattern = new(
|
||||||
|
@"^(X[+-]?\d+\.?\d*Y[+-]?\d+\.?\d*)G85(X[+-]?\d+\.?\d*Y[+-]?\d+\.?\d*)$",
|
||||||
|
RegexOptions.Compiled);
|
||||||
|
|
||||||
|
// 解析 X 或 Y 坐标值的子模式
|
||||||
|
private static readonly Regex XValuePattern = new(
|
||||||
|
@"X([+-]?\d+\.?\d*)", RegexOptions.Compiled);
|
||||||
|
private static readonly Regex YValuePattern = new(
|
||||||
|
@"Y([+-]?\d+\.?\d*)", RegexOptions.Compiled);
|
||||||
|
|
||||||
|
// 刀具定义行模式(在头部,如 T01C0.799H05000Z+0.000S060.00)
|
||||||
|
private static readonly Regex ToolDefinitionPattern = new(
|
||||||
|
@"^T\d+C", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 对钻带内容执行涨缩
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">原始钻带内容</param>
|
||||||
|
/// <param name="kx">X 方向缩放倍率</param>
|
||||||
|
/// <param name="ky">Y 方向缩放倍率</param>
|
||||||
|
/// <returns>缩放后的钻带内容</returns>
|
||||||
|
public static string Scale(string content, double kx, double ky)
|
||||||
|
{
|
||||||
|
if (content == null)
|
||||||
|
throw new ArgumentNullException(nameof(content));
|
||||||
|
|
||||||
|
var lines = content.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
|
||||||
|
var result = new List<string>(lines.Length);
|
||||||
|
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
string trimmed = line.Trim();
|
||||||
|
|
||||||
|
// 空行直接保留
|
||||||
|
if (string.IsNullOrEmpty(trimmed))
|
||||||
|
{
|
||||||
|
result.Add(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刀具定义行(TxxC...):严格原样保留
|
||||||
|
if (ToolDefinitionPattern.IsMatch(trimmed))
|
||||||
|
{
|
||||||
|
result.Add(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// G85 槽孔行:缩放中心点,保持槽长不变
|
||||||
|
var slotMatch = SlotPattern.Match(trimmed);
|
||||||
|
if (slotMatch.Success)
|
||||||
|
{
|
||||||
|
result.Add(ScaleSlotLine(trimmed, kx, ky));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 普通坐标行:X...Y...
|
||||||
|
var coordMatch = CoordinatePattern.Match(trimmed);
|
||||||
|
if (coordMatch.Success)
|
||||||
|
{
|
||||||
|
result.Add(ScaleCoordinateLine(trimmed, kx, ky));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其余行原样保留(M48, %, Txx, M30 等)
|
||||||
|
result.Add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Join("\r\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缩放普通坐标行
|
||||||
|
/// </summary>
|
||||||
|
private static string ScaleCoordinateLine(string line, double kx, double ky)
|
||||||
|
{
|
||||||
|
var xMatch = XValuePattern.Match(line);
|
||||||
|
var yMatch = YValuePattern.Match(line);
|
||||||
|
|
||||||
|
if (!xMatch.Success || !yMatch.Success)
|
||||||
|
return line;
|
||||||
|
|
||||||
|
double xOrig = double.Parse(xMatch.Groups[1].Value);
|
||||||
|
double yOrig = double.Parse(yMatch.Groups[1].Value);
|
||||||
|
|
||||||
|
long xNew = (long)Math.Round(xOrig * kx);
|
||||||
|
long yNew = (long)Math.Round(yOrig * ky);
|
||||||
|
|
||||||
|
return $"X{xNew}Y{yNew}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缩放 G85 槽孔行
|
||||||
|
/// 缩放中心点,保持原始矢量恢复起止点(槽长不变)
|
||||||
|
/// </summary>
|
||||||
|
private static string ScaleSlotLine(string line, double kx, double ky)
|
||||||
|
{
|
||||||
|
var slotMatch = SlotPattern.Match(line);
|
||||||
|
if (!slotMatch.Success)
|
||||||
|
return line;
|
||||||
|
|
||||||
|
// 解析起点坐标
|
||||||
|
var startPart = slotMatch.Groups[1].Value;
|
||||||
|
var xStartMatch = XValuePattern.Match(startPart);
|
||||||
|
var yStartMatch = YValuePattern.Match(startPart);
|
||||||
|
double xStart = double.Parse(xStartMatch.Groups[1].Value);
|
||||||
|
double yStart = double.Parse(yStartMatch.Groups[1].Value);
|
||||||
|
|
||||||
|
// 解析终点坐标
|
||||||
|
var endPart = slotMatch.Groups[2].Value;
|
||||||
|
var xEndMatch = XValuePattern.Match(endPart);
|
||||||
|
var yEndMatch = YValuePattern.Match(endPart);
|
||||||
|
double xEnd = double.Parse(xEndMatch.Groups[1].Value);
|
||||||
|
double yEnd = double.Parse(yEndMatch.Groups[1].Value);
|
||||||
|
|
||||||
|
// 计算中心点
|
||||||
|
double cx = (xStart + xEnd) / 2.0;
|
||||||
|
double cy = (yStart + yEnd) / 2.0;
|
||||||
|
|
||||||
|
// 缩放中心点
|
||||||
|
long cxNew = (long)Math.Round(cx * kx);
|
||||||
|
long cyNew = (long)Math.Round(cy * ky);
|
||||||
|
|
||||||
|
// 保持原始矢量(槽长不变)
|
||||||
|
long dx = (long)Math.Round((xEnd - xStart) / 2.0);
|
||||||
|
long dy = (long)Math.Round((yEnd - yStart) / 2.0);
|
||||||
|
|
||||||
|
// 恢复起止点
|
||||||
|
long newStartX = cxNew - dx;
|
||||||
|
long newStartY = cyNew - dy;
|
||||||
|
long newEndX = cxNew + dx;
|
||||||
|
long newEndY = cyNew + dy;
|
||||||
|
|
||||||
|
return $"X{newStartX}Y{newStartY}G85X{newEndX}Y{newEndY}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -97,7 +97,8 @@
|
|||||||
<Button Width="120" Height="30" Content="调整刀序" Margin="0,0,15,0" Click="AdjustToolOrder_Click"/>
|
<Button Width="120" Height="30" Content="调整刀序" Margin="0,0,15,0" Click="AdjustToolOrder_Click"/>
|
||||||
<Button Width="120" Height="30" Content="导出孔数" Margin="0,0,15,0" Click="ExportHoleCount_Click"/>
|
<Button Width="120" Height="30" Content="导出孔数" Margin="0,0,15,0" Click="ExportHoleCount_Click"/>
|
||||||
<Button Name="ClearParametersButton" Width="120" Height="30" Content="清空参数" Margin="0,0,15,0" Click="ClearParameters_Click"/>
|
<Button Name="ClearParametersButton" Width="120" Height="30" Content="清空参数" Margin="0,0,15,0" Click="ClearParameters_Click"/>
|
||||||
<Button Name="GeneratePpDrillTapeButton" Width="120" Height="30" Content="生成PP钻带" Click="GeneratePpDrillTape_Click"/>
|
<Button Name="GeneratePpDrillTapeButton" Width="120" Height="30" Content="生成PP钻带" Margin="0,0,15,0" Click="GeneratePpDrillTape_Click"/>
|
||||||
|
<Button Name="ScaleDrillTapeButton" Width="120" Height="30" Content="涨缩" Click="ScaleDrillTape_Click"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ namespace DrillTools
|
|||||||
AdjustToolOrder,
|
AdjustToolOrder,
|
||||||
ExportHoleCount,
|
ExportHoleCount,
|
||||||
ClearParameters,
|
ClearParameters,
|
||||||
GeneratePpDrillTape
|
GeneratePpDrillTape,
|
||||||
|
ScaleDrillTape
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class StartupSelectionWindow : Window
|
public partial class StartupSelectionWindow : Window
|
||||||
@@ -17,6 +18,7 @@ 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,
|
||||||
|
bool canScaleDrillTape = 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,
|
bool isPpDrillTape = false, double ppXSpacing = 0, double ppYSpacing = 0,
|
||||||
bool hasOuter3175Spacing = false, double outer3175XSpacing = 0, double outer3175YSpacing = 0)
|
bool hasOuter3175Spacing = false, double outer3175XSpacing = 0, double outer3175YSpacing = 0)
|
||||||
@@ -37,6 +39,7 @@ namespace DrillTools
|
|||||||
};
|
};
|
||||||
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;
|
||||||
|
ScaleDrillTapeButton.Visibility = canScaleDrillTape ? Visibility.Visible : Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AdjustToolOrder_Click(object sender, RoutedEventArgs e)
|
private void AdjustToolOrder_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -62,5 +65,11 @@ namespace DrillTools
|
|||||||
SelectedAction = StartupAction.GeneratePpDrillTape;
|
SelectedAction = StartupAction.GeneratePpDrillTape;
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ScaleDrillTape_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
SelectedAction = StartupAction.ScaleDrillTape;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user