二.SolidWorks 二次开发之 IModelDoc2

访问项目 Github仓库

查看在线文档

使用Nuget:

PM> Install-Package Du.SolidWorks -Version 0.1.1

去Github查看本节源代码

一.IModelDoc2 介绍

首先我们来看ModelDoc2的对象关系图,使用ModelDoc2 我们可以转换为AssemblyDoc PartDoc DrawingDoc等特定文档类型,也可以获取ModelDocExtension等,从而调用很多常见的api,可以说IModelDoc2接口几乎是开发中使用频率最高的接口。

IModelDoc2 Object Model

二.通过IModelDoc2获取文档类型

1.1 直接获取文档类型,GetType方法直接放回的此文档的类型,注意和 csharp 反射 自带的GetType区分

        /// 
        /// 获取文档类型
        /// 
        /// 
        /// 
        public static swDocumentTypes_e GetTypeEx(this IModelDoc2 doc)
        {
            return (swDocumentTypes_e)doc.GetType();
        }

1.2 判断此文档是否是某种类型

既然可以获取文档类型,我们便可以通过简单的封装来判断文档类型

        /// 
        /// 是否是特定的类型
        /// 
        /// 
        /// 文档类型  
        /// 
        public static bool IsSpecType(this IModelDoc2 doc,swDocumentTypes_e type)
        {
            return doc.GetTypeEx() == type;
        }

三.通过IModelDoc2 获取特定文档的接口

我们知道了ModelDoc2 可以转换为特定文档接口,我们也可以通过IModelDoc2的GetType方法获取文档类型,下面我们就可以将其转换为特定文档的接口。代码很简单,直接转换类型即可,实现如下。

1.转换为PartDoc

        /// 
        /// 转换为零件文档
        /// 
        /// 
        /// 
        public static PartDoc AsPartDoc(this IModelDoc2 doc)
        {
            if (doc.GetTypeEx() != swDocumentTypes_e.swDocPART)
            {
                throw new Exception("错误的类型,无法转换为PartDoc");
            }
            return (PartDoc)doc;
        }

2.转换为AssemblyDoc

        /// 
        /// 转换为装配体
        /// 
        /// 
        /// 
        public static AssemblyDoc AsAssemblyDoc(this IModelDoc2 doc)
        {
            if (doc.GetTypeEx() != swDocumentTypes_e.swDocASSEMBLY)
            {
                throw new Exception("错误的类型,无法转换为PartDoc");
            }
            return (AssemblyDoc)doc;
        }

3.转换为DrawingDoc

        /// 
        /// 转换为 
        /// 
        /// 
        /// 
        public static IDrawingDoc AsDrawingDoc(this IModelDoc2 doc)
        {
            if (doc.GetTypeEx() != swDocumentTypes_e.swDocDRAWING)
            {
                throw new Exception("错误的类型,无法转换为PartDoc");
            }
            return (IDrawingDoc)doc;
        }

四.IModelDoc2 中对特征的获取

4.1 获取所有特征

通过IFeatureManager 中的GetFeatures便可以获取所有特征,下面代码通过此方法使得直接可以通过IModelDoc2接口获取所有特征

        /// 
        /// 获取所有的某种类型的特征
        /// 
        /// 
        /// 
        public static IEnumerable GetFeats(this IModelDoc2 doc)
        {
            var feats = doc.FeatureManager
                .GetFeatures(false)
                  as IFeature[];
            return feats;
        }

4.2 按顺序获取所有特征

上面的方法只是获取了所有的特征,但特征的顺序是随机的,下面的方法按照特征顺序遍历了所有的特征

        /// 
        /// 按顺序遍历特征
        /// 
        /// 
        /// 
        /// 
        public static List GetFirstToLastFeats(this IModelDoc2 doc,bool TopOnly = true)
        {
            List feats = new List();

            var Feat = doc.FirstFeature() as IFeature;

            while (Feat != null)
            {
                feats.Add(Feat);
                if (!TopOnly)
                {
                    var SubFeat = Feat.GetFirstSubFeature() as IFeature;
                    while (SubFeat != null)
                    {
                        feats.Add(SubFeat);
                        SubFeat = SubFeat.GetNextSubFeature() as IFeature;
                    }
                }
                Feat = Feat.GetNextFeature() as IFeature;
            }

            return feats;
        }

对上面的方法,也可以返回一个IEnumerable 来实现懒加载,提高某些场景下的速度。

4.3 通过特征获取所有的特征尺寸

       /// 
        /// 获取所有的特征尺寸
        /// 
        /// 
        /// 
        /// 
        public static List> GetModelDispalyDimensions(this ModelDoc2 doc,bool TopOnly = true)
        {
            var listResult = new List>();

            var feats = doc.FeatureManager.GetFeaturesEx(TopOnly);

            foreach (var feat in feats)
            {
                var dims = feat.GetDisplayDimensions();
                foreach (var dim in dims)
                {
                    listResult.Add(new KeyValuePair(feat.CastObj(), dim));
                }
            }
            return listResult;
        }

五.IModelDoc2中的屏幕和视图的变换

5.1将屏幕坐标变换的模型空间

        /// 
        /// 从一个给定的屏幕上的X,Y变换到视图模型中的点和方向
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static PointDirection3 ScreenToView(this IModelDoc2 doc,MathUtility math ,int x, int y)
        {
            var view = doc.ActiveView as IModelView;
            var t = view.Transform.Inverse() as MathTransform;

            var eye = math.PointEx(new[] { x, y, 0.0 });

            var look = math.ZAxis();

            eye = eye.MultiplyTransform(t) as MathPoint;
            look = look.MultiplyTransform(t) as MathVector;

            return new PointDirection3(eye.ToVector3(), look.ToVector3());
        }

5.2 模型空间到屏幕坐标

同样我们可以计算出模型空间到屏幕坐标

        /// 
        /// 空间点变换到屏幕
        /// 
        /// 
        /// 
        /// 
        /// 
        public static Vector2 ViewToScreen(this IModelDoc2 doc, MathUtility math , Vector3 point)
        {

            var view = doc.ActiveView as IModelView;
            var t = view.Transform as MathTransform;
            var mathPoint = point.ToSwMathPoint(math);
            mathPoint = mathPoint.MultiplyTransform(t) as MathPoint;
            var v3 = mathPoint.ToVector3();
            return new Vector2(v3.X, v3.Y);
        }

六.关于SolidWorks对象的PID

在SolidWorks中对于特征,实体,边线面等对象都具有一个PID,PID即Persist ID ,持久性ID。此ID一般在创建后变不会改变。通过比较此ID,我们可以判断出这是不是我们以前操作过的对象。实现一些比较性的功能

详细介绍

6.1 pidcollector 获取PID

在SolidWork安装目录下,我的在C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\api 。SolidWorks提供了一个直接获取PID的工具


pidcollector.exe

通过此工具,我们可以方便的获取SolidWorks中某个对象的PID

PID

6.2 通过代码获取SolidWorks对象的PID

        /// 
        /// 获取实体PID
        /// Because we should use the same version of `GetPersistReference` and `GetObjectFromPersistReference` resp.
        /// and the persist reference is saved with the models we should never ever use another version of the two methods.
        /// For more details see http://help.solidworks.com/2016/english/api/sldworksapi/SolidWorks.interop.sldworks~SolidWorks.interop.sldworks.IModelDocExtension~GetPersistReference3.html#remarksSection
        /// 
        /// 
        /// 
        /// 
        /// 
        public static byte[] GetPersistReference(this IModelDoc2 modelDoc, T obj)
        {
            return modelDoc.Extension.GetPersistReference3(obj) as byte[];
        }

6.3 通过PID获取对象

这是PID最神奇的地方,我们可以在某些地方记录下某个对象的PID,然后我们可以通过这个PID再次获取某个SolidWorks对象。

        /// 
        /// Get an entity from its persist id.
        /// 
        /// Because we should use the same version of `GetPersistReference` and `GetObjectFromPersistReference` resp.
        /// and the persist reference is saved with the models we should never ever use another version of the two methods.
        /// For more details see http://help.solidworks.com/2016/english/api/sldworksapi/SolidWorks.interop.sldworks~SolidWorks.interop.sldworks.IModelDocExtension~GetPersistReference3.html#remarksSection
        /// 
        /// 
        /// 
        /// 
        public static object GetObjectFromPersistReference(this IModelDoc2 doc, byte[] persistId)
        {
            int errorCode;
            var @object = doc.Extension.GetObjectByPersistReference3(persistId, out errorCode);
            var result = (swPersistReferencedObjectStates_e)errorCode;
            if (result != swPersistReferencedObjectStates_e.swPersistReferencedObject_Ok)
            {
                throw new Exception($"GetObjectByPersistReference3 returned {result}");
            }
            return @object;
        }

七 .IModelDoc2 中的配置

通过ModelDoc2 可以获取配置信息

7.1 获取所有配置

        /// 
        /// Get all configurations
        /// 
        /// 
        /// 
        public static IEnumerable GetConfigurations(this IModelDoc2 modelDoc)
        {
            var configs = modelDoc
            .GetConfigurationNames()
            as string[];

            return  configs.Select(name => (Configuration)modelDoc.GetConfigurationByName(name));
        }

7.2 通过ID获取配置

        /// 
        /// Look-up a configuration based on it's ID
        /// 
        /// 
        /// 
        /// 
        public static Configuration GetConfigurationFromID(this IModelDoc2 modelDoc, int ID)
        {
            return modelDoc
                .GetConfigurations()
                .FirstOrDefault(config => config.GetID() == ID);
        }

总结

IModelDoc2 提供了对一个SolidWorks基础文档的很多访问和操作,当然有些更多的操作被转发到其他对象。但IModelDoc2接口依然是SolidWorks开发中不可避免的接口,其丰富的方法还需要去探索。

你可能感兴趣的:(二.SolidWorks 二次开发之 IModelDoc2)