C# SolidWorks 二次开发 API — 修改全局变量的值

今天来简单讲一下如何修改方程式中的一些数据,有时候一些简单的模型我们就可以利用这个全局变量来控制模型.

如下图: 我设定了零件的高度方程式与全局变量h相等.

等到我们需要更新高度时,就可以直接修改这个全局变量,做到更简单的参数化方式,这个全局变量可以是上级装配体中的信息.

 下面来具体演示下如何找api:

打开api帮助文件,搜索关键字 globalvariable,就会发现右侧的实例,是一个获取信息的.

This example shows how to get the values of equations.

//-----------------------------------------
// Preconditions:
// 1. Open public_documents\samples\tutorial\api\partequations.sldprt.
// 2. Open the Immediate window.
//
// Postconditions:
// 1. Gets each equation's value and index and whether the 
//    equation is a global variable. 
// 2. Examine the Immediate window.
//------------------------------------------
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using System.Runtime.InteropServices;
using System;
using System.Diagnostics;
 
namespace Macro1CSharp.csproj
{
    public partial class SolidWorksMacro
    {
        public void Main()
        {
            ModelDoc2 swModel = default(ModelDoc2);
            EquationMgr swEqnMgr = default(EquationMgr);
            int i = 0;
            int nCount = 0;
 
            swModel = (ModelDoc2)swApp.ActiveDoc;
            swEqnMgr = (EquationMgr)swModel.GetEquationMgr();
            Debug.Print("File = " + swModel.GetPathName());
            nCount = swEqnMgr.GetCount();
            for (i = 0; i < nCount; i++)
            {
                Debug.Print("  Equation(" + i + ")  = " + swEqnMgr.get_Equation(i));
                Debug.Print("    Value = " + swEqnMgr.get_Value(i));
                Debug.Print("    Index = " + swEqnMgr.Status);
                Debug.Print("    Global variable? " + swEqnMgr.get_GlobalVariable(i));
            }
 
        }
 
        /// <summary>
        ///  The SldWorks swApp variable is pre-assigned for you.
        /// </summary>
        public SldWorks swApp;
    }
}

我们参考这段代码来完成方程式信息的读取: 增加按钮写代码.

 参照帮助文件写完的版本大概为:

运行一下:

 

下面我们来做修改:

private void butGlobalVariables_Click(object sender, EventArgs e)
        {
            //连接solidworks
            ISldWorks swApp = Utility.ConnectToSolidWorks();

            if (swApp != null)
            {
                //获取当前模型
                ModelDoc2 swModel = (ModelDoc2)swApp.ActiveDoc;
                //定义方程式管理器
                EquationMgr swEqnMgr = default(EquationMgr);

                int i = 0;
                int nCount = 0;

                if (swModel != null)
                {
                    swEqnMgr = (EquationMgr)swModel.GetEquationMgr();
                    // nCount = swEqnMgr.GetCount();
                    //for (i = 0; i < nCount; i++)
                    //{
                    //    Debug.Print("  Equation(" + i + ")  = " + swEqnMgr.get_Equation(i));
                    //    Debug.Print("    Value = " + swEqnMgr.get_Value(i));
                    //    Debug.Print("    Index = " + swEqnMgr.Status);
                    //    Debug.Print("    Global variable? " + swEqnMgr.get_GlobalVariable(i));
                    //}

                    //修改高度为60

                    if (SetEquationValue(swEqnMgr, "h", 60))
                    {
                        swModel.ForceRebuild3(true);
                    }
                    else
                    {
                        MessageBox.Show("没有找到这个值!");
                    }
                }
            }
        }

        #region 修改全局变量所用到的方法

        public bool SetEquationValue(EquationMgr eqMgr, string name, double newValue)
        {
            int index = GetEquationIndexByName(eqMgr, name);

            if (index != -1)
            {
                eqMgr.Equation[index] = "\"" + name + "\"=" + newValue;

                return true;
            }
            else
            {
                return false;
            }
        }

        //通过名字找方程式的位置
        private int GetEquationIndexByName(EquationMgr eqMgr, string name)
        {
            int i;
            for (i = 0; i <= eqMgr.GetCount() - 1; i++)
            {
                var eqName = eqMgr.Equation[i].Split('=')[0].Replace("=", "");

                eqName = eqName.Substring(1, eqName.Length - 2); // removing the "" symbols from the name

                if (eqName.ToUpper() == name.ToUpper())
                {
                    return i;
                }
            }

            return -1;
        }

        #endregion 修改全局变量所用到的方法

到此,零件高度变成了60, 这一节先讲这么多吧.

最终代码请到码云或者github上下载.

C# SolidWorks 二次开发 API —获取预览图

最近有网友问到如何在界面上简单的显示一个预览图,就类似于资源管理器中显示的图片。
今天来带大家找一找,首先在我共享的中文翻译中搜索一下:“预览

我们找到了几个有用的。
先看这一个: 第一列是Web 帮助的地址,当然也可以去本地api帮助中查看。


vba中还有个例 子
问题是这帮助写的只能是进程内使用,像exe还不行。
继续看下面的,有另一个方法:

这个方法看描述好像可以使用:
Gets the specified preview bitmap of a document and saves it as a Windows bitmap file (.bmp) using the specified filename.

写上代码:

ISldWorks swApp = Utility.ConnectToSolidWorks();

            //此处路径请自己确保存在。
            string fileName = @"D:\09_Study\CSharpAndSolidWorks\CSharpAndSolidWorks\TemplateModel\bodies.sldasm";

            string configName = "Default";

            string bitmapPathName = @"D:\09_Study\CSharpAndSolidWorks\CSharpAndSolidWorks\TemplateModel\bodies.bmp";

            var status = swApp.GetPreviewBitmapFile(fileName, configName, bitmapPathName);

            if (System.IO.File.Exists(bitmapPathName))
            {
                swApp.SendMsgToUser("预览图获取完成。");
            }

结果出来的颜色有点怪,不理想。

到这里想了下,我们可以直接获取系统资源管理器的预览图,而不需要利用solidworks来处理。
这个就直接百度,找一找资源就行了。
我找了个类,直接调用 ,就可以获取到文件了,后缀是.li ,很奇怪的格式。

找到文件,复制到当前零件的文件夹。改后缀为.bmp,ok了。

这是利用系统的api的获取的,如果只是单配置零件也比较完美了。这种好像不能获取不同配置的预览图。

在查询api帮助的时候发现,在Document Manager API 中也提供了获取预览图的功能。
注意,这里需要一个key, 正版用户请找对应的代理商获取,每一个版本的key都不一样,并且带公司名称。


里面还有实例,那我们就来试试吧:
测试时发现,document mgr从2018开始,只支持64位程序。所以测试时大家要把编译的选项改成x64位的,不然一直会报无法创建dll的实例。

 			const string sLicenseKey = "your_license_key"; //这个不好公开。请下载代码 

            string sDocFileName = fileName;

            SwDMClassFactory swClassFact = default(SwDMClassFactory);
            SwDMApplication swDocMgr = default(SwDMApplication);
            SwDMDocument swDoc = default(SwDMDocument);
            SwDMDocument10 swDoc10 = default(SwDMDocument10);
            SwDmDocumentType nDocType = 0;
            SwDmDocumentOpenError nRetVal = 0;
            SwDmPreviewError nError = 0;

            // Determine type of SOLIDWORKS file based on file extension
            if (sDocFileName.EndsWith("sldprt"))
            {
                nDocType = SwDmDocumentType.swDmDocumentPart;
            }
            else if (sDocFileName.EndsWith("sldasm"))
            {
                nDocType = SwDmDocumentType.swDmDocumentAssembly;
            }
            else if (sDocFileName.EndsWith("slddrw"))
            {
                nDocType = SwDmDocumentType.swDmDocumentDrawing;
            }
            else
            {
                // Probably not a SOLIDWORKS file,
                // so cannot open
                nDocType = SwDmDocumentType.swDmDocumentUnknown;
                return;
            }

            swClassFact = new SwDMClassFactory();
            swDocMgr = (SwDMApplication)swClassFact.GetApplication(sLicenseKey);
            swDoc = (SwDMDocument)swDocMgr.GetDocument(sDocFileName, nDocType, true, out nRetVal);
            Debug.Print("File = " + swDoc.FullName);
            Debug.Print(" Version = " + swDoc.GetVersion());
            Debug.Print(" Author = " + swDoc.Author);
            Debug.Print(" Comments = " + swDoc.Comments);
            Debug.Print(" CreationDate = " + swDoc.CreationDate);
            Debug.Print(" Keywords = " + swDoc.Keywords);
            Debug.Print(" LastSavedBy = " + swDoc.LastSavedBy);
            Debug.Print(" LastSavedDate = " + swDoc.LastSavedDate);
            Debug.Print(" Subject = " + swDoc.Subject);
            Debug.Print(" Title = " + swDoc.Title);

            swDoc10 = (SwDMDocument10)swDoc;
            // SwDMDocument10::GetPreviewBitmap throws an unmanaged COM exception
            // for out-of-process C# console applications
            // Use the following code in SOLIDWORKS C# macros and add-ins
            object objBitMap = swDoc10.GetPreviewBitmap(out nError);
            System.Drawing.Image imgPreview = PictureDispConverter.Convert(objBitMap);
            imgPreview.Save(bitmapPathName, System.Drawing.Imaging.ImageFormat.Bmp);
            imgPreview.Dispose();

            Debug.Print(" Preview stream = " + swDoc10.PreviewStreamName);

执行成功之后 ,我们颜色不对的预览图就被替换成功了。

当然 ,现在也还是只是获取了最后保存的那个配置的缩略图。
如何获取别的配置的呢?
这个方法的备注里面有说明: 需要用别的方法:

里面有个实例:
Get PNG Preview Bitmap and Stream for Configuration Example (C#)
核心就在这里,需要去遍历配置。当然 ,如果知道配置名称,就不需要遍历一次了。
下面的代码我没有测试哈

 swCfgMgr = swDoc.ConfigurationManager;
 
                Debug.Print("File = " + swDoc.FullName);
                Debug.Print("Active configuration name = " + swCfgMgr.GetActiveConfigurationName());
                vCfgNameArr = (string[])swCfgMgr.GetConfigurationNames();
 
                foreach (string vCfgName in vCfgNameArr)
                {
 
                    swCfg = (SwDMConfiguration7)swCfgMgr.GetConfigurationByName(vCfgName);
                    // SwDMConfiguration7::GetPreviewPNGBitmap throws an unmanaged COM exception 
                    // for out-of-process C# console applications
                    // Use the following code in SOLIDWORKS C# macros and add-ins 
                    object objBitMap = swCfg.GetPreviewPNGBitmap(out nError);
                    System.Drawing.Image imgPreview = PictureDispConverter.Convert(objBitMap);
                    imgPreview.Save("C:\\temp\\" + vCfgName + ".PNG", System.Drawing.Imaging.ImageFormat.Png);
                    imgPreview.Dispose();
 
                    Debug.Print(" " + vCfgName);
                    Debug.Print(" PNG preview stream = " + swCfg.PreviewPNGStreamName);
 
                    Debug.Print(" ");
                }