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;
            }
        }
    }
}
相关推荐
花开月满西楼14 小时前
零基础速学SolidWorks2026【曲面】曲面缝合
3d建模·solidworks·机械设计·机械绘图绘制
花开月满西楼18 小时前
零基础速学SolidWorks2026【曲面】删除面
3d建模·solidworks·机械设计·机械绘图绘制
花开月满西楼1 天前
零基础速学SolidWorks2026【曲面】加厚曲面
3d建模·solidworks·机械设计·机械绘图绘制
花开月满西楼4 天前
零基础速学SolidWorks2026【曲面】边界曲面和等距曲面
3d建模·solidworks·机械设计·机械绘图绘制
花开月满西楼4 天前
零基础速学SolidWorks2026【曲面】平面区域和填充曲面
3d建模·solidworks·机械设计·机械绘图绘制
蓝悦无人机5 天前
SOLIDWORKS高级应用之方程
solidworks·参数化建模·if 判断语句
花开月满西楼5 天前
零基础速学SolidWorks2026【曲面】分割线
3d建模·solidworks·机械设计·机械绘图绘制
花开月满西楼7 天前
零基础速学SolidWorks2026【曲面】建模核心基础
solidworks·机械设计·机械绘图绘制
花开月满西楼8 天前
零基础速学SolidWorks2026【草图】绘制、编辑命令和约束
solidworks·机械设计
solidwork_s11 天前
一根骨架撑起整套钢架—SOLIDWORKS焊件实战诀窍
solidworks