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

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(" ");
                }

posted @
2020-05-09 14:09 
painezeng  阅读(
292)  评论(
0
编辑 
收藏 
举报

C# SolidWorks 二次开发 API —注释引用点的坑

C# SolidWorks 二次开发 API —注释引用点的坑

最近有个小需求,就是要把注释箭头指向的点的坐标提取出来。
刚开始发现Note.GetAttachPos功能,Annotation.GetPosition有这个功能。
但是经过测试发现,当注释的引线是多折线的时候,上两个函数就是读取的位置有时候对,有时候不对。
本来可以想着把所有的第二种换成第一种,那么获取的时候就应该正确了,但是发现API里面还不能直接转换。

经过大量的调试发现,如果使用的是多折线,但是只有一条折线信息的时候,可能是对的,如果是多折的,基本上不对。
当鼠标移动到引线上时,默认的一段直线直接显示的是注释的图标,当移动到是多段折线上时,显示的是另一个图标,说明它们不是一个对象。而更像是一个组合体。

经过api的检查,发现了这个多折线有一个专门的对象。里面是由多个线的信息组成。

然后又发现Annotation中两个方法 GetMultiJogLeaderCount 和 GetMultiJogLeaders,所以就更显明了。
在获取注释对象 Note的引用点位置时,需要做一个判断。
当GetMultiJogLeaderCount > 0 时,那么说明它是一个多折线的注释,需要使用 MultiJogLeader 来获取信息。遍历其它的关键点坐标。
这个坐标和视图的位置与比例有一定关联,它默认是的整个图纸的坐标。如果需要转换到视图中,还需要做个计算。

下面是一段宏的代码:

Option Explicit
Sub main()
    Dim swApp           As SldWorks.SldWorks
    Dim swModel         As ModelDoc2
    Dim swDraw          As DrawingDoc
    Dim swSelMgr        As SelectionMgr
    Dim swNote          As Note
    Dim swView          As View
    Dim viewPos         As Variant
    Dim notePos         As Variant
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    
     Dim ann As Annotation
     
    If Not swModel Is Nothing Then
        If swModel.GetType <> swDocumentTypes_e.swDocDRAWING Then Exit Sub
        Set swDraw = swModel
        Set swSelMgr = swModel.SelectionManager
        
        Dim selLeaders As SldWorks.MultiJogLeader
          Dim lineData As Variant
          
          
          If swSelMgr.GetSelectedObjectType3(1, -1) <> swSelectType_e.swSelNOTES Then Exit Sub
          
        Set swNote = swSelMgr.GetSelectedObject6(1, 0)
        
        Set swView = swDraw.ActiveDrawingView
        viewPos = swView.Position
        notePos = swNote.GetAttachPos
       
        Set ann = swNote.GetAnnotation
                  
         If ann.GetMultiJogLeaderCount > 0 Then
         
         
         Set selLeaders = ann.GetMultiJogLeaders(0)
         
           If selLeaders Is Nothing = False Then
           
            
            lineData = selLeaders.GetLineAtIndex(0)
            For i = 0 To selLeaders.GetLineCount - 1
            
                 lineData = selLeaders.GetLineAtIndex(i)
                If Not IsEmpty(lineData) Then
                    
                    Debug.Print ("x:" & Math.Round((lineData(1) - viewPos(0)) * 1000# / swView.ScaleDecimal, 4))
                    Debug.Print ("y:" & Math.Round((lineData(2) - viewPos(1)) * 1000# / swView.ScaleDecimal, 4))
                                
                    
                End If
            Next i
           End If
           
           Else
           
         
         End If

           
       
        
' 'ann.UseDocDispLeader = True
       'Debug.Print (swView.Angle * 57.295779513)
' Debug.Print (Math.Round((notePos(0) - viewPos(0)) * 1000# / swView.ScaleDecimal, 4))
' Debug.Print (Math.Round((notePos(1) - viewPos(1)) * 1000# / swView.ScaleDecimal, 4))
' Debug.Print
    End If
End Sub

反之,按正常的GetAttachPos获取对象就可以了。

posted @
2020-05-02 16:55 
painezeng  阅读(
138)  评论(
0
编辑 
收藏 
举报