solidworks改零件的方程式 c#

csharp 复制代码
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using System;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace tools
{
    /// <summary>
    /// 方程式管理器 - 提供读取和修改 SolidWorks 方程式的功能
    /// </summary>
    public class EquationModifier
    {
        /// <summary>
        /// 显示方程式修改对话框并处理用户输入
        /// </summary>
        /// <param name="swApp">SolidWorks 应用程序对象</param>
        /// <param name="swModel">当前模型文档</param>
        /// <returns>操作结果消息</returns>
        public static string ModifyEquations(SldWorks swApp, ModelDoc2 swModel)
        {
            try
            {
                if (swApp == null || swModel == null)
                {
                    Debug.WriteLine("SolidWorks 或模型未初始化");
                    return "SolidWorks 或模型未初始化";
                }

                // 关键:设置 Visible = true 来触发文档加载(参考 asm2do 和 asm2check 的做法)
                swModel.Visible = true;

                // 获取方程式管理器
                EquationMgr eqnMgr = (EquationMgr)swModel.GetEquationMgr();
                if (eqnMgr == null)
                {
                    Debug.WriteLine("无法获取方程式管理器");
                    swApp.SendMsgToUser("无法获取方程式管理器");
                    return "无法获取方程式管理器";
                }

                int eqnCount = eqnMgr.GetCount();
                if (eqnCount <= 0)
                {
                    Debug.WriteLine("当前模型没有方程式");
                    swApp.SendMsgToUser("当前模型没有方程式");
                    return "当前模型没有方程式";
                }

                // 显示方程式修改对话框
                if (!ShowEquationDialog(eqnMgr, swModel, swApp))
                {
                    // 用户取消,恢复文档可见性状态
                    swModel.Visible = false;
                    return "用户取消了操作";
                }

                // 重建模型以应用更改
                swModel.EditRebuild3();

                // 修改完成,隐藏文档(参考 asm2check 的做法)
                swModel.Visible = false;

                Console.WriteLine("方程式修改完成");
               
                return "方程式修改完成";
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"修改方程式失败:{ex.Message}");
                swApp?.SendMsgToUser($"修改方程式失败:{ex.Message}");
                return $"修改方程式失败:{ex.Message}";
            }
        }

        /// <summary>
        /// 显示方程式修改对话框
        /// </summary>
        private static bool ShowEquationDialog(EquationMgr eqnMgr, ModelDoc2 swModel, SldWorks swApp)
        {
            using (var form = new Form())
            {
                form.Text = "修改方程式";
                form.Size = new Size(600, 450);
                form.StartPosition = FormStartPosition.CenterParent;
                form.MinimumSize = new Size(500, 400);
                form.TopMost = true;

                var mainPanel = new TableLayoutPanel();
                mainPanel.Dock = DockStyle.Fill;
                mainPanel.ColumnCount = 1;
                mainPanel.RowCount = 4;
                mainPanel.Padding = new Padding(10);
                mainPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
                mainPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
                mainPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
                mainPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));

                // 标题标签
                var titleLabel = new Label();
                titleLabel.Text = "选择要修改的方程式:";
                titleLabel.Font = new Font(titleLabel.Font, FontStyle.Bold);
                titleLabel.AutoSize = true;
                mainPanel.Controls.Add(titleLabel, 0, 0);

                // 方程式列表框
                var listBox = new ListBox();
                listBox.Dock = DockStyle.Fill;
                listBox.IntegralHeight = false;
                listBox.SelectionMode = SelectionMode.One;

                for (int i = 0; i < eqnMgr.GetCount(); i++)
                {
                    string equation = eqnMgr.get_Equation(i);
                    bool isGlobalVar = eqnMgr.get_GlobalVariable(i);
                    string typeStr = isGlobalVar ? "[全局变量]" : "[尺寸方程]";
                    listBox.Items.Add($"{i + 1}. {typeStr} {equation}");
                }

                mainPanel.Controls.Add(listBox, 0, 1);

                // 新值输入区域(固定布局,避免在宿主环境中被挤压不可见)
                var inputPanel = new TableLayoutPanel();
                inputPanel.ColumnCount = 1;
                inputPanel.RowCount = 2;
                inputPanel.Dock = DockStyle.Fill;
                inputPanel.Padding = new Padding(0, 10, 0, 0);
                inputPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
                inputPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));

                var valueLabel = new Label();
                valueLabel.Text = "新值(支持表达式,如 150+231-18):";
                valueLabel.AutoSize = true;
                valueLabel.Dock = DockStyle.Fill;
                inputPanel.Controls.Add(valueLabel, 0, 0);

                var textBox = new TextBox();
                textBox.Dock = DockStyle.Top;
                textBox.Width = 520;
                textBox.MinimumSize = new Size(300, 28);
                textBox.Margin = new Padding(0, 6, 0, 0);
                textBox.Text = "";
                inputPanel.Controls.Add(textBox, 0, 1);

                // 切换方程式时,自动带出原值,便于在原值基础上增删
                listBox.SelectedIndexChanged += (s, e) =>
                {
                    if (listBox.SelectedIndex < 0) return;
                    string equation = eqnMgr.get_Equation(listBox.SelectedIndex);
                    textBox.Text = ExtractEquationValue(equation);
                    textBox.Focus();
                    textBox.SelectAll();
                };

                mainPanel.Controls.Add(inputPanel, 0, 2);

                // 按钮面板
                var buttonPanel = new FlowLayoutPanel();
                buttonPanel.FlowDirection = FlowDirection.RightToLeft;
                buttonPanel.AutoSize = true;
                buttonPanel.WrapContents = false;
                buttonPanel.Padding = new Padding(0, 10, 0, 0);

                var cancelButton = new Button();
                cancelButton.Text = "取消";
                cancelButton.DialogResult = DialogResult.Cancel;
                cancelButton.Width = 80;

                var okButton = new Button();
                okButton.Text = "确定";
                okButton.DialogResult = DialogResult.OK;
                okButton.Width = 80;

                buttonPanel.Controls.Add(cancelButton);
                buttonPanel.Controls.Add(okButton);

                mainPanel.Controls.Add(buttonPanel, 0, 3);

                form.Controls.Add(mainPanel);
                form.AcceptButton = okButton;
                form.CancelButton = cancelButton;
                form.Shown += (s, e) =>
                {
                    textBox.Focus();
                    textBox.SelectAll();
                };

                // 默认选中第一个方程式
                if (listBox.Items.Count > 0)
                {
                    listBox.SelectedIndex = 0;
                }

                if (form.ShowDialog() == DialogResult.OK && listBox.SelectedIndex >= 0)
                {
                    string newValue = textBox.Text.Trim();
                    if (string.IsNullOrEmpty(newValue))
                    {
                        Debug.WriteLine("用户未输入新值");
                        swApp.SendMsgToUser("请输入新的方程式值");
                        return false;
                    }

                    // 修改选中的方程式
                    int selectedIndex = listBox.SelectedIndex;
                    return ModifyEquationByIndex(eqnMgr, swModel, selectedIndex, newValue, swApp);
                }

                return false;
            }
        }

        /// <summary>
        /// 根据索引修改方程式
        /// </summary>
        private static bool ModifyEquationByIndex(EquationMgr eqnMgr, ModelDoc2 swModel, 
            int selectedIndex, string newValue, SldWorks swApp)
        {
            try
            {
                if (selectedIndex < 0 || selectedIndex >= eqnMgr.GetCount())
                {
                    Debug.WriteLine("选择的方程式索引无效");
                    swApp.SendMsgToUser("选择的方程式索引无效");
                    return false;
                }

                // 尝试计算用户输入的表达式
                string calculatedValue = EvaluateExpression(newValue);
                
                // 获取原始方程式名称
                string originalEquation = eqnMgr.get_Equation(selectedIndex);
                string[] originalParts = originalEquation.Split(new[] { '=' }, 2);
                
                if (originalParts.Length < 2)
                {
                    Debug.WriteLine("原始方程式格式错误");
                    swApp.SendMsgToUser("原始方程式格式错误");
                    return false;
                }

                string equationName = originalParts[0]; // 包含引号的名称部分

                // 构建新的方程式(使用计算后的值)
                string newEquation = $"{equationName}={calculatedValue}";

                // 设置新的方程式
                eqnMgr.set_Equation(selectedIndex, newEquation);

                Debug.WriteLine($"方程式已更新: {newEquation}");
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"修改方程式时出错: {ex.Message}");
                swApp?.SendMsgToUser($"修改方程式时出错: {ex.Message}");
                return false;
            }
        }

        private static string ExtractEquationValue(string equation)
        {
            if (string.IsNullOrWhiteSpace(equation))
            {
                return "";
            }

            var parts = equation.Split(new[] { '=' }, 2);
            if (parts.Length < 2)
            {
                return equation.Trim();
            }

            return parts[1].Trim();
        }

        /// <summary>
        /// 计算数学表达式的值
        /// </summary>
        /// <param name="expression">数学表达式,如 "150+231-18"</param>
        /// <returns>计算结果字符串</returns>
        private static string EvaluateExpression(string expression)
        {
            try
            {
                // 如果表达式不包含运算符,直接返回原值
                if (!expression.Contains('+') && !expression.Contains('-') && 
                    !expression.Contains('*') && !expression.Contains('/') &&
                    !expression.Contains('(') && !expression.Contains(')'))
                {
                    return expression;
                }

                // 使用 DataTable.Compute 方法计算表达式
                var dataTable = new System.Data.DataTable();
                var result = dataTable.Compute(expression, "");
                
                // 将结果转换为合适的格式
                if (result is double doubleResult)
                {
                    // 如果是整数,去掉小数点
                    if (doubleResult == Math.Floor(doubleResult))
                    {
                        return ((int)doubleResult).ToString();
                    }
                    else
                    {
                        // 保留两位小数
                        return doubleResult.ToString("F2");
                    }
                }
                else if (result is int intResult)
                {
                    return intResult.ToString();
                }
                else
                {
                    return result.ToString();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"表达式计算失败: {ex.Message},使用原始值");
                // 如果计算失败,返回原始值
                return expression;
            }
        }
    }
}
相关推荐
njsgcs8 小时前
solidworks 按partdox包围框改零件名字 c#
solidworks
njsgcs5 天前
solidworks自动标注折弯3 OneBend Select4 GetVisibleComponents
solidworks
njsgcs6 天前
solidworks自动标注折弯2 找到折弯面了,差如何优雅的用面标注
solidworks
njsgcs9 天前
获得solidworks 3d零件的包围框 长宽高 boundingbox c#
开发语言·c#·solidworks
rqtz17 天前
【机器人】ROS2配置solidworks模型转换的URDF文件
ros2·urdf·solidworks
ddsoft12325 天前
制造企业PLM应用新趋势:按需部署
软件·solidworks·产品生命周期数据管理
ddsoft1231 个月前
仿真应用的六大误区
仿真·solidworks
njsgcs1 个月前
solidworks 导出dwg 带映射模板 c# 图纸比例一比一导出
c#·solidworks
铁头七娃2 个月前
Solidworks 2024 根据机器人装配体,生成urdf文件
机器人·ros·solidworks