使用C#对Solidworks二次开发并且制作一款小软件(二)

前言

        第一篇帖子说的是如何通过winform搭建的软件窗口打开Solidworks文件,本篇将介绍如何获取Solidworks文件在绘制过程中人工标注出的尺寸信息,并且通过软件进行参数化设计。

1、窗口设计

        在上一个帖子的基础上,先提前在窗口创建两个button,分别用来获取尺寸信息,选中参数编辑。以及一个listbox,用来显示获取的Solidworks文件的零件参数。

        我的设计逻辑是:点击获取尺寸按钮后,将获取到的尺寸参数全部显示在listbox中,可以通过单选或者多选这些参数,并且在点击编辑参数后弹出新的窗口(form2),用于写入编辑信息,并且把编辑的信息应用到实体零件中。其中form1的窗口设计如下图所示:

        在listbox的属性设置中将SelectionMode中默认的“one”,改为MultiSimple,此举是为了可以多选参数,如下图所示:

 2、获取零件尺寸

        这一Part中主要使用Solidworks官方提供的 Feature接口和DisplayDimension接口。首先定义两个方法:

        在文章(一)中的代码中,已将第一步打开的软件和线程模型保存

  1. public ISldWorks swApp { get; private set; }

  2. public ModelDoc2 swModel { get; private set; } // 存储当前打开的模型

         TraverseFeatures 方法递归遍历 SolidWorks 模型中的所有特征,包括顶级特征和其子特征。根据参数设置,它可以调用 ShowDimensionForFeature 方法,显示每个特征的尺寸信息。

         ShowDimensionForFeature 方法负责显示特定特征的所有尺寸信息,并将这些信息添加到窗体的 listBox1 控件中。这个方法在遍历过程中被调用,用于输出每个特征的具体尺寸数据。       

        接下来是对获取尺寸按钮(Get_dimension)设置点击事件:

private void Get_dimension_Click(object sender, EventArgs e)
{
    listBox1.Items.Clear();

    if (swModel != null)
    {
        Feature feat = swModel.FirstFeature();
        if (feat != null)
        {
            TraverseFeatures(feat, true, true, this);
        }
        else
        {
            MessageBox.Show("未找到特征。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    else
    {
        MessageBox.Show("未找到有效的模型文档。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

        在点击事件开始设置对listbox的清除,保证每次点击都会显示最新的参数,达到刷新的效果。并从当前打开的 SolidWorks 模型中获取所有特征的尺寸信息。如果模型存在并且包含特征,它将调用 TraverseFeatures 方法遍历所有特征并显示其尺寸信息。在其中还增加了对模型和线程检测的部分,如果在点击按钮后没有检测到相应的模型和线程,则会提示错误。

3、测试一

        先打开solidworks 2022,然后通过打开文件按钮打开test01

         其后点击获取(刷新)尺寸,显示

        成功。

4、编辑尺寸功能

        首先,要对编辑尺寸按钮进行点击事件的代码设计,代码如下

private void button4_Click(object sender, EventArgs e)
{
    //检查solidworks是否连接
    if (!IsSolidWorksConnected())
    {
        MessageBox.Show("请打开一个SolidWorks文件并读取参数", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    // 检查是否有有效模型
    if (swModel == null)
    {
        MessageBox.Show("未检测到有效模型", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    //检查是否选择了任意项
    if (listBox1.SelectedItems.Count == 0)
    {
        MessageBox.Show("请选择有效项", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }


    List<string> selectedFeatureNames = new List<string>();
    foreach (var item in listBox1.SelectedItems)
    {
        string listItem = item.ToString();
        int startIndex = listItem.IndexOf("-->") + 3;
        int endIndex = listItem.LastIndexOf("-->");
        string featureName = listItem.Substring(startIndex, endIndex - startIndex).Trim();
        selectedFeatureNames.Add(featureName);
    }
    Form2 form2 = new Form2(swModel, selectedFeatureNames);
    form2.ShowDialog();

}

        因为单个窗口面板能填入的组件有限,所以设计了form2,在选择listbox1的项后,用于显示用户选中的对应项以及对应的textbox供用户去输入修改的数值。上一个代码的最后设置了对form2窗口显示的代码,在执行完编辑尺寸的按钮功能后,显示form2的窗口,并且将swModel(模型文件)以及seletedFeatureNames(用户选择的列表项)传入到form2中。首先新建一个窗口form2。

        并且在窗口中添加一个更改尺寸(Editor)按钮,用于将用户选择修改的参数应用到实际的模型中,位置随便,因为代码还会对按钮的位置进行调整,保证按钮始终出现在尺寸项的下方,如下图:

        我设计的想法是将显示的组件数与上一步中用户选中的listbox1的项目数相匹配,并且生成对应的label以及textbox,所以没有选择在设计器上面去添加组件,而是直接用代码生成,包括label的文本显示,以及textbox,去获取用户在其中输入的数值,其中form2的组件部分代码如下:

public partial class Form2 : Form
{
    private ModelDoc2 swModel;
    private List<string> selectedFeatureNames;
    private string backupFilePath; // 用于保存模型状态的临时文件路径

    public Form2(ModelDoc2 swModel, List<string> selectedFeatureNames)
    {
        InitializeComponent();

        this.swModel = swModel;
        this.selectedFeatureNames = selectedFeatureNames;

        int yPos = 20; // 初始Y轴位置

        //根据用户选中的项目数生成对应数目的待修改项
        foreach (var featureName in selectedFeatureNames)
        {

            Label label1 = new Label();
            label1.Text = "待修改特征:" + featureName;
            label1.Location = new System.Drawing.Point(10, yPos);
            label1.AutoSize = true;
            this.Controls.Add(label1);

            TextBox textBox = new TextBox();
            textBox.Name = featureName; // 使用 featureName 作为 TextBox 的名称
            textBox.Location = new System.Drawing.Point(400, yPos);
            this.Controls.Add(textBox);

            Label label2 = new Label();
            label2.Text = "修改该特征的尺寸为:";
            label2.Location = new System.Drawing.Point(280, yPos);
            label2.AutoSize = true;
            this.Controls.Add(label2);

            Label label3 = new Label();
            label3.Text = "单位(mm)";
            label3.Location = new System.Drawing.Point(500, yPos);
            label3.AutoSize = true;
            this.Controls.Add(label3);

            yPos += 30; // 更新Y轴位置
        }

        Editor.Location = new System.Drawing.Point(100, yPos + 10); // 更改尺寸按钮位置            
        this.ClientSize = new System.Drawing.Size(600, yPos + 60); // 更新Form2的大小
    }
}

5、测试二

        还是test01文件为例,选择前三项 

         点击编辑尺寸按钮,显示如下图:

        成功。

6、应用尺寸

        接下来是更改尺寸按钮的功能设计,话不多说直接上代码

private void Editor_Click(object sender, EventArgs e)
{
    Form1 form1 = (Form1)Application.OpenForms["Form1"];
    ModelDoc2 modelDoc2 = form1.swModel;

    //检查是否打开了有效模型
    if (modelDoc2 == null)
    {
        MessageBox.Show("未读取有效模型,请重新打开文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    bool allDimensionsUpdated = true;
    List<string> nonEditableDimensions = new List<string>();

    try
    {
        foreach (var featureName in selectedFeatureNames)
        {
            // 寻找名为 featureName 的 TextBox 控件
            Control[] controls = this.Controls.Find(featureName, true);
            if (controls.Length > 0 && controls[0] is TextBox textBox)
            {
                if (double.TryParse(textBox.Text, out double newValue))
                {
                    bool dimensionUpdated = false;

                    if (swModel != null)
                    {
                        Feature feat = swModel.FirstFeature();
                        while (feat != null)
                        {
                            var displayDim = (DisplayDimension)feat.GetFirstDisplayDimension();
                            while (displayDim != null)
                            {
                                var dimen = (Dimension)displayDim.GetDimension();
                                if (dimen.GetNameForSelection() == featureName)
                                {
                                    // 检查是否为参考尺寸或不可编辑的尺寸
                                    int dimType = dimen.GetType(); // 获取尺寸类型

                                    // 过滤掉不可编辑的参考尺寸类型,假设 2 表示参考尺寸
                                    if (dimType != 2) // 根据实际值修改
                                    {
                                        dimen.SystemValue = newValue * 0.001; // 转换为米
                                        dimensionUpdated = true;
                                    }
                                    else
                                    {
                                        nonEditableDimensions.Add(featureName);
                                        allDimensionsUpdated = false;
                                    }
                                }
                                displayDim = (DisplayDimension)feat.GetNextDisplayDimension(displayDim);
                            }
                            feat = feat.GetNextFeature();
                        }
                    }

                    if (!dimensionUpdated)
                    {
                        nonEditableDimensions.Add(featureName);
                        allDimensionsUpdated = false;
                    }
                }
                else
                {
                    MessageBox.Show($"尺寸输入无效: {textBox.Text}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            else
            {
                MessageBox.Show($"找不到名称为 {featureName} 的 TextBox 控件。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        if (allDimensionsUpdated)
        {
            swModel.EditRebuild3();
            MessageBox.Show("所有尺寸更新成功", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        else
        {
            string nonEditableMessage = "以下尺寸无法修改:\n" + string.Join("\n", nonEditableDimensions);
            MessageBox.Show(nonEditableMessage, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show($"更新参数时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

         代码有点不太美观,各位将就着看,可能有一些重复的部分。在这段代码中,首先获取当前 Form1 实例以及当前打开的 ModelDoc2 对象。接着,检查是否有有效的模型文档被打开,如果没有,则显示错误消息并返回。接下来,初始化两个变量:allDimensionsUpdated 用于跟踪所有尺寸是否都被成功更新,而 nonEditableDimensions 则用于存储无法更新的尺寸名称。
        随后,建立一个循环,遍历selectedFeatureNames的列表,该列表包含了需要更新尺寸的特征名称。对于列表中的每一个特征名称,找到与之对应名称的 TextBox 控件。将其中的文本解析为一个双精度浮点数 newValue。解析成功后,进入一个嵌套的循环,从当前模型的第一个特征开始遍历,寻找与特征名称匹配的尺寸。
        在特征的遍历过程中,使用 GetFirstDisplayDimension() 和 GetNextDisplayDimension() 方法来遍历特征的所有显示尺寸。对于每一个显示尺寸,获取其 Dimension 对象,并检查该尺寸的名称是否与需要更新的特征名相匹配。如果匹配,进一步检查尺寸的类型,以确定是否可以编辑该尺寸。如果尺寸可以编辑,使用 SystemValue 属性来更新尺寸值,并确保数值是以米为单位(因为 SolidWorks 默认使用毫米作为单位,所以需要乘以 0.001 来转换为米)。
        如果发现尺寸不可编辑或者没有找到与特征名称匹配的尺寸,则将该特征名称添加到 nonEditableDimensions 列表中,并标记 allDimensionsUpdated 为 false。如果所有可编辑的尺寸都被成功更新,则调用 EditRebuild3() 方法来重建模型,以确保所有的更改都应用到了模型上。最后,根据 allDimensionsUpdated 的状态,显示相应的消息框给用户,告知用户更新的结果。
        整个过程还包括了一些错误处理机制,比如在更新过程中遇到任何异常,我们会捕获异常并显示一条错误消息。此外,如果无法解析 TextBox 中的文本为数字,或者找不到与特征名称匹配的 TextBox 控件,也会显示相应的错误消息。

7、测试三

        还是和测试二一样,选中前三个项开始编辑,分别设置为25-150-25

        点击更改尺寸按钮,提示更改成功

        可以看到,尺寸更改成功。

8、结语

        此功能适合对图纸比较熟悉的用户,可以对照特征名以及对应的参数数值去批量修改,但是针对于不熟悉图纸的用户可能需要对照软件中的特征名去修改,不是很便捷。本帖更多还是分享一种参数化零件设计的思路,同时我也在考虑是否有更直观的尺寸显示方法。因为本人入门没有多久,目前还只是代码的雏形,功能有点局限,欢迎各方大佬指点,下期更新自定义属性批量修改的功能。

C# SolidWorks二次开发是指使用C#编程语言来扩展和定制SolidWorks软件的功能。下面是进行C# SolidWorks二次开发的步骤: 1. 环境配置: - 首先,确保您已经安装了SolidWorks软件和Visual Studio开发环境。 - 然后,安装SolidWorks API SDK。您可以在SolidWorks安装包中找到"SolidWorks API SDK.msi"文件,并按照安装向导进行安装。 2. 创建插件Addin: - 打开Visual Studio,并创建一个新的C#项目。 - 在项目中,添加对SolidWorks API的引用。您可以在项目的引用中添加SolidWorks.Interop.sldworks和SolidWorks.Interop.swcommands等引用。 - 创建一个类,并实现SolidWorks的事件接口,例如ISwAddin或ISwAddin2。 - 实现所需的功能,例如创建自定义工具栏、菜单或按钮,并实现其相应的事件处理程序。 3. 运行和调试: - 在Visual Studio中编译和生成项目。 - 将生成的插件文件(.dll文件)复制到SolidWorks的插件目录中,一般为"C:\ProgramData\SolidWorks\SOLIDWORKS 20XX\addins"。 - 启动SolidWorks软件,您应该能够看到您创建的自定义工具栏、菜单或按钮。 - 单击按钮或执行其他操作来测试和调试您的插件功能。 通过以上步骤,您可以开始使用C#编程语言进行SolidWorks二次开发,实现自定义的功能和工具,以满足您的需求。请确保在开发过程中参考官方文档和其他相关教程,以便更好地理解和掌握C# SolidWorks二次开发的技术。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值