用C#来开发CAD插件,含源代码
转自原文 用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类分别演示了命令行、右键菜单、工具条的实现。注释得非常清楚了,就不做多解释。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; 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; namespace Test { public class Class1 : Autodesk.AutoCAD.Runtime.IExtensionApplication { ContextMenuExtension m_ContextMenu;//定义右键菜单 PaletteSet palSet;//定义工具栏按钮 //初始化方法,这里加了一个面板工具栏和右键菜单。如果不要右键菜单,注释即可 public void Initialize() { AddContextMenu();//添加面板工具栏 AddPalette();//添加右键菜单 } //卸载方法 public void Terminate() { RemoveContextMenu(); } //有CommandMethod标注,是提供给CAD使用的命令 [CommandMethod("HelloWorld")] public void HelloWorld() { //这段代码的作用是弹出一个提示 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage("深渊码奴编写:第一个外部门程序CAD!"); } #region 添加一个右键菜单,并实现画一个圆的功能 /// <summary>点击响应事件,创建一个圆 /// /// </summary> /// <param name="o"></param> /// <param name="e"></param> private void MyMenuItem_OnClick(object o, EventArgs e) { using (DocumentLock doclock = Application.DocumentManager.MdiActiveDocument.LockDocument()) { //创建一个红色的圆 Database db = HostApplicationServices.WorkingDatabase; using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; Circle cir = new Circle(new Point3d(10, 10, 0), Vector3d.ZAxis, 100); cir.ColorIndex = 1; btr.AppendEntity(cir); trans.AddNewlyCreatedDBObject(cir, true); trans.Commit(); } } } /// <summary>添加右键菜单项 /// /// </summary> private void AddContextMenu() { m_ContextMenu = new ContextMenuExtension(); m_ContextMenu.Title = "深渊码奴的自定义菜单"; Autodesk.AutoCAD.Windows.MenuItem mi; mi = new Autodesk.AutoCAD.Windows.MenuItem("创建圆"); //关联菜单项的处理函数 mi.Click += MyMenuItem_OnClick; m_ContextMenu.MenuItems.Add(mi); Application.AddDefaultContextMenuExtension(m_ContextMenu); } /// <summary>移除菜单项 /// /// </summary> private void RemoveContextMenu() { if (m_ContextMenu != null) { Application.RemoveDefaultContextMenuExtension(m_ContextMenu); m_ContextMenu = null; } } #endregion [CommandMethod("ShowModalForm")] public void ShowModalForm() { Form1 modalForm = new Form1(); Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(modalForm); } [CommandMethod("AddPalette")] public void AddPalette() { Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; try { if (palSet == null) { palSet = new Autodesk.AutoCAD.Windows.PaletteSet("我的面板集"); palSet.Style = PaletteSetStyles.ShowTabForSingle; palSet.Style = PaletteSetStyles.NameEditable; palSet.Style = PaletteSetStyles.ShowPropertiesMenu; palSet.Style = PaletteSetStyles.ShowAutoHideButton; palSet.Style = PaletteSetStyles.ShowCloseButton; palSet.Opacity = 90; palSet.MinimumSize = new System.Drawing.Size(300, 300); System.Windows.Forms.UserControl myPageCtrl = new ModelessForm();//注意这里是加载自己写的用户控件 //myPageCtrl.Dock = System.Windows.Forms.DockStyle.Fill; palSet.Add("我的页面", myPageCtrl); palSet.Visible = true; } } catch { ed.WriteMessage("创建面板集错误"); } } } }
2,CAD展现工具条,添加一个用户控件,取名为ModelessForm。两行代码显示Form1窗体而已。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; namespace Test { public partial class ModelessForm : UserControl { public ModelessForm() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Form1 modalForm = new Form1(); Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(modalForm); } } }
3,Form1窗体的功能,是根据长宽画一个矩形,矩形的四个角分别画一个圆。因为在CAD里运行,所以使用的类库和正常C#的不同。这里是实现的重点,根据需要写自己的代码。class1类是一个框架,基本不用改。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; 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; namespace Test { public partial class Form1 : Form { public Form1() { InitializeComponent(); } float C;//长 float K;//宽 /// <summary> 画CAD图,根据计算出的坐标 /// /// </summary> void drawCAD() { Point3d p0 = new Point3d(0,0,0); Point3d p1 = new Point3d(C,0,0); Point3d p2 = new Point3d(C, K, 0); Point3d p3 = new Point3d(0, K, 0); using (DocumentLock doclock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument()) { // Database db = HostApplicationServices.WorkingDatabase; using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //画4条直线的矩形 List<Line> lins = new List<Line>(); lins.Add(new Line(p0, p1)); lins.Add(new Line(p1, p2)); lins.Add(new Line(p2, p3)); lins.Add(new Line(p3, p0)); foreach (Line line in lins) { btr.AppendEntity(line); trans.AddNewlyCreatedDBObject(line, true); } //画圆,这里直接用矩形的四个点来画 List<Point3d> points = new List<Point3d>(); points.Add(p0); points.Add(p1); points.Add(p2); points.Add(p3); List<Circle> cirs = new List<Circle>(); foreach (Point3d p3d in points) { int R = 20; cirs.Add(new Circle(p3d, Vector3d.ZAxis, R)); } foreach (Circle cir in cirs) { cir.ColorIndex = 1; btr.AppendEntity(cir); trans.AddNewlyCreatedDBObject(cir, true); } trans.Commit(); } } } private void button1_Click(object sender, EventArgs e) { this.C = Convert.ToInt32(this.textBox1.Text);//int转成float一定可以,所以可以把int的值直接赋给float this.K = Convert.ToInt32(this.textBox2.Text); this.drawCAD(); this.Close(); } } }
整个工程打包上来,有兴趣的朋友跑起来玩玩。很少写博客,不知道哪里能上传,放个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也能实现。
花几天时间让自己掌握多一件技术也是件开心的事,也可以拿去镇镇设计工程师,让他们知道码农的强大。
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。