用C#来开发CAD插件,含源代码

CAD插件看起来很神秘,其实一个合格码农经过几天就能快速掌握。没什么秘密,开发CAD插件和winform一样简单学几个类库用法就是(只是太多人不喜欢知识分享),在CAD里展现界面和winform略有不同(整个项目工程在文章的最后有下载)。

学习CAD插件开发的动机是为了薪水,由于公司是做显示屏和触摸屏的,养了一堆CAD的设计工程师拿着8K以上的薪水,当时我做为信息系统开发人员才拿4K,4个人要开发维护整个公司(2万人,几十个部门)的系统,感觉严重不平衡,便挑战一下设计工程师,借此提高自身价值。

适用案例,公司做手机屏要放UV胶来贴合,用CAD画一个边框加一些线条。看着设计工程师们画画CAD也有那么多薪水,心里不平衡就搞出一个按照参数自动出图的东西。当然实际的项目比我放出的复杂得多,这里只是讲讲CAD插件技术,不涉及实际项目。总之无论多复杂,凡是根据参数生成固定图形的,CAD插件程序都可以胜任。

效果展示:

1,命令行:

2,右键菜单:

3,工具条,CAD内嵌界面,和winform一样简单

闲话少说,直接上原理和代码:

0,
项目效果查看:
a:在CAD2006的命令行输入netload,加载Test.dll
b1:在命令行输入helloworld可以看到命令功能
b2:右键可以看到右键菜单,画一个红色的圆
b3:左边工具面板多了一个工具条,有个界面可以输入各种参数来画一个组合图形


1,建一个xindows窗体程序项目,设置输出为类库
2,引用acdbmgd.dll和acmgd.dll
3,引用如下命名空间
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Windows.ToolPalette;
using Autodesk.AutoCAD.Windows;


4,在Form1上规划界面和后台代码。重点看代码如何实现

5,计划是CAD上增加一个面板按钮,点击按钮就打开Form1来自动画图。
   这里我们加一个用户控件,拖一个按钮,按钮方法写:
Form1 modalForm = new Form1();          
Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(modalForm);
注意这里仅仅是打开的窗体的方式选择了AutoCAD的方式。  
想建立一整套工具栏,就多拉几个按钮。按4的方法写好每个按钮执行的代码(可以要个Form1这样的界面,也可以不要,自由选择)

6,把这个项目导出还需要一个类来辅助
先看初始化Initialize()和Terminate()方法。这里给CAD加了一个面板工具栏和右键菜单,以及一些命令行

1,这个class1类分别演示了命令行、右键菜单、工具条的实现。注释得非常清楚了,就不做多解释。 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using Autodesk.AutoCAD.EditorInput;
  6 using Autodesk.AutoCAD.ApplicationServices;
  7 using Autodesk.AutoCAD.Runtime;
  8 using Autodesk.AutoCAD.DatabaseServices;
  9 using Autodesk.AutoCAD.Geometry;
 10 using Autodesk.AutoCAD.Windows.ToolPalette;
 11 using Autodesk.AutoCAD.Windows;
 12 
 13 namespace Test
 14 {
 15     public class Class1 : Autodesk.AutoCAD.Runtime.IExtensionApplication
 16     {
 17         ContextMenuExtension m_ContextMenu;//定义右键菜单 
 18         PaletteSet palSet;//定义工具栏按钮
 19 
 20         //初始化方法,这里加了一个面板工具栏和右键菜单。如果不要右键菜单,注释即可
 21         public void Initialize()
 22         {
 23             AddContextMenu();//添加面板工具栏
 24             AddPalette();//添加右键菜单
 25         }
 26 
 27         //卸载方法
 28         public void Terminate()
 29         {
 30             RemoveContextMenu();
 31         }
 32 
 33 
 34         //有CommandMethod标注,是提供给CAD使用的命令
 35         [CommandMethod("HelloWorld")]
 36         public void HelloWorld()
 37         {
 38             //这段代码的作用是弹出一个提示
 39             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
 40             ed.WriteMessage("深渊码奴编写:第一个外部门程序CAD!");
 41         }
 42 
 43  
 44 
 45         #region 添加一个右键菜单,并实现画一个圆的功能
 46         /// <summary>点击响应事件,创建一个圆
 47         /// 
 48         /// </summary>
 49         /// <param name="o"></param>
 50         /// <param name="e"></param>
 51         private void MyMenuItem_OnClick(object o, EventArgs e)
 52         {
 53             using (DocumentLock doclock = Application.DocumentManager.MdiActiveDocument.LockDocument())
 54             {
 55                 //创建一个红色的圆
 56                 Database db = HostApplicationServices.WorkingDatabase;
 57                 using (Transaction trans = db.TransactionManager.StartTransaction())
 58                 {
 59                     BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
 60                     BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
 61                     Circle cir = new Circle(new Point3d(10, 10, 0), Vector3d.ZAxis, 100);
 62                     cir.ColorIndex = 1;
 63                     btr.AppendEntity(cir);
 64                     trans.AddNewlyCreatedDBObject(cir, true);
 65                     trans.Commit();
 66                 }
 67             }
 68         }
 69 
 70         /// <summary>添加右键菜单项
 71         /// 
 72         /// </summary>
 73         private void AddContextMenu()
 74         {
 75             m_ContextMenu = new ContextMenuExtension();
 76             m_ContextMenu.Title = "深渊码奴的自定义菜单";
 77             Autodesk.AutoCAD.Windows.MenuItem mi;
 78             mi = new Autodesk.AutoCAD.Windows.MenuItem("创建圆");
 79             //关联菜单项的处理函数
 80             mi.Click += MyMenuItem_OnClick;
 81             m_ContextMenu.MenuItems.Add(mi);
 82 
 83             Application.AddDefaultContextMenuExtension(m_ContextMenu);
 84         }
 85         /// <summary>移除菜单项
 86         /// 
 87         /// </summary>
 88         private void RemoveContextMenu()
 89         {
 90             if (m_ContextMenu != null)
 91             {
 92 
 93                 Application.RemoveDefaultContextMenuExtension(m_ContextMenu);
 94                 m_ContextMenu = null;
 95             }
 96         }
 97         #endregion
 98 
 99 
100         [CommandMethod("ShowModalForm")]
101         public void ShowModalForm()
102         {
103             Form1 modalForm = new Form1();
104             Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(modalForm);
105         }
106 
107         [CommandMethod("AddPalette")]
108         public void AddPalette()
109         {
110             Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
111             try
112             {
113                 if (palSet == null)
114                 {
115                     palSet = new Autodesk.AutoCAD.Windows.PaletteSet("我的面板集");
116 
117                     palSet.Style = PaletteSetStyles.ShowTabForSingle;
118                     palSet.Style = PaletteSetStyles.NameEditable;
119                     palSet.Style = PaletteSetStyles.ShowPropertiesMenu;
120                     palSet.Style = PaletteSetStyles.ShowAutoHideButton;
121                     palSet.Style = PaletteSetStyles.ShowCloseButton;
122                     palSet.Opacity = 90;
123                     palSet.MinimumSize = new System.Drawing.Size(300, 300);
124                     System.Windows.Forms.UserControl myPageCtrl = new ModelessForm();//注意这里是加载自己写的用户控件
125                     //myPageCtrl.Dock = System.Windows.Forms.DockStyle.Fill; 
126                     palSet.Add("我的页面", myPageCtrl);
127                     palSet.Visible = true;
128                 }
129             }
130 
131             catch
132             {
133                 ed.WriteMessage("创建面板集错误");
134             }
135 
136 
137         }
138 
139 
140         
141     }
142 }
143 
144     
View Code

2,CAD展现工具条,添加一个用户控件,取名为ModelessForm。两行代码显示Form1窗体而已。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Drawing;
 5 using System.Data;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 
10 namespace Test
11 {
12     public partial class ModelessForm : UserControl
13     {
14         public ModelessForm()
15         {
16             InitializeComponent();
17         }
18 
19         private void button1_Click(object sender, EventArgs e)
20         {
21             Form1 modalForm = new Form1();
22             Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(modalForm);
23         }
24     }
25 }
View Code

3,Form1窗体的功能,是根据长宽画一个矩形,矩形的四个角分别画一个圆。因为在CAD里运行,所以使用的类库和正常C#的不同。这里是实现的重点,根据需要写自己的代码。class1类是一个框架,基本不用改。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using Autodesk.AutoCAD.EditorInput;
10 using Autodesk.AutoCAD.ApplicationServices;
11 using Autodesk.AutoCAD.Runtime;
12 using Autodesk.AutoCAD.DatabaseServices;
13 using Autodesk.AutoCAD.Geometry;
14 using Autodesk.AutoCAD.Windows.ToolPalette;
15 using Autodesk.AutoCAD.Windows;
16 namespace Test
17 {
18     public partial class Form1 : Form
19     {
20         public Form1()
21         {
22             InitializeComponent();
23         }
24         float C;//
25         float K;//
26         /// <summary> 画CAD图,根据计算出的坐标
27         /// 
28         /// </summary>
29         void drawCAD()
30         {
31             Point3d p0 = new Point3d(0,0,0);
32             Point3d p1 = new Point3d(C,0,0);
33             Point3d p2 = new Point3d(C, K, 0);
34             Point3d p3 = new Point3d(0, K, 0);
35            
36             using (DocumentLock doclock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
37             {
38                 //
39                 Database db = HostApplicationServices.WorkingDatabase;
40                 using (Transaction trans = db.TransactionManager.StartTransaction())
41                 {
42                     BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
43                     BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
44 
45 
46                     //画4条直线的矩形
47                     List<Line> lins = new List<Line>();
48                     lins.Add(new Line(p0, p1));
49                     lins.Add(new Line(p1, p2));
50                     lins.Add(new Line(p2, p3));
51                     lins.Add(new Line(p3, p0));
52                     foreach (Line line in lins)
53                     {
54                         btr.AppendEntity(line);
55                         trans.AddNewlyCreatedDBObject(line, true);
56                     }
57 
58 
59                     //画圆,这里直接用矩形的四个点来画
60                     List<Point3d> points = new List<Point3d>();
61                     points.Add(p0);
62                     points.Add(p1);
63                     points.Add(p2);
64                     points.Add(p3);
65                     List<Circle> cirs = new List<Circle>();
66                     foreach (Point3d p3d in points)
67                     {
68                         int R = 20;
69                         cirs.Add(new Circle(p3d, Vector3d.ZAxis, R));
70                     }
71                     foreach (Circle cir in cirs)
72                     {
73                         cir.ColorIndex = 1;
74                         btr.AppendEntity(cir);
75                         trans.AddNewlyCreatedDBObject(cir, true);
76                     }
77 
78                     trans.Commit();
79                 }
80             }
81         }
82         private void button1_Click(object sender, EventArgs e)
83         {
84             this.C = Convert.ToInt32(this.textBox1.Text);//int转成float一定可以,所以可以把int的值直接赋给float
85             this.K = Convert.ToInt32(this.textBox2.Text);
86             this.drawCAD();
87             this.Close();
88         }
89     }
90 }
View Code

整个工程打包上来,有兴趣的朋友跑起来玩玩。很少写博客,不知道哪里能上传,放个360网盘分享吧,http://yunpan.cn/Q5t2pTptiUm4b。

https://files.cnblogs.com/files/zkp2010/CAD%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E2%80%94%E2%80%94%E4%BB%A5CAD2006%E4%B8%BA%E4%BE%8B.rar

 CAD插件技术真心不难,无非是画点线条,CAD内部能实现的,C#调用acdbmgd.dll和acmgd.dll也能实现。

花几天时间让自己掌握多一件技术也是件开心的事,也可以拿去镇镇设计工程师,让他们知道码农的强大。

原文地址:https://www.cnblogs.com/zkp2010/p/3100084.html