1.看的一个微信公众号文章:
1)https://mp.weixin.qq.com/mp/homepage?__biz=MzA3NzI3MjgyNQ==&hid=1&sn=34d1ac6a455db6b01e0c83bb32333f42&scene=18#wechat_redirect
2)https://mp.weixin.qq.com/mp/homepage?__biz=MzA3NzI3MjgyNQ==&hid=3&sn=fb3bd421a3420297fa22d0f2666910e4&scene=18#wechat_redirect
2.环境搭建看这两篇文章
1)https://mp.weixin.qq.com/s?__biz=MzA3NzI3MjgyNQ==&mid=2247483682&idx=1&sn=eb1fa959eb7d98921c6fe22f731b6fe5&scene=19#wechat_redirect
2)https://mp.weixin.qq.com/s?__biz=MzA3NzI3MjgyNQ==&mid=2247484071&idx=1&sn=bbb03fde51e1f5bd0d970102d0882f18&scene=19#wechat_redirect
经验总结:开发前一定先确定好开发环境版本,建议C#,如果你选择了C#,那么要注意.NET版本,ObjectARX版本,VS向导的版本,
AutoCAD版本,VS版本(VS和VS Code不一样)等;
3.知道一个AutoCAD二次开发的官网,https://www.autodesk.com/developer-network/platform-technologies/autocad
4.在D:\other_tools\CAD\AUTOCAD\AutoCAD 2018\Support\acad2018.lsp 文件中加(command “netload” “D:\other_tools\CAD\AUTOCAD\AutoCAD 2018\Plugins\CaculateArea\caculate_projected_area.dll”),可以在启动的时候加载dll插件
5.加载实现IExtensionApplication接口做初始化
6.如果在IExtensionApplication接口的Initialize方法中创建显示Ribbon菜单,需要用委托模式
7.还有问题要多去QQ群,论坛等,多沟通交流能很快解决问题
8.下面是开发的第一个Demo插件的实例,可以参考下
关键代码:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using System.IO;
using Autodesk.Windows;
[assembly: ExtensionApplication(typeof(caculate_projected_area.ProgramClass))] //启动时加载工具栏,注意typeof括号里的类库名
namespace caculate_projected_area
{
//实现接口
public class ProgramClass : IExtensionApplication
{
//重写接口里的初始化方法
public void Initialize()
{
ComponentManager.ItemInitialized += ComponentManager_ItemInitialized;
}
//重写接口的终止方法
public void Terminate()
{
//清理程序,可空
}
public void ComponentManager_ItemInitialized(object sender, RibbonItemEventArgs e)
{
if (ComponentManager.Ribbon != null)
{
CreateRibbon();//添加ribbon菜单的函数
ComponentManager.ItemInitialized -= ComponentManager_ItemInitialized;
}
}
//创建菜单栏
public void CreateRibbon()
{
CurPaht.curPaht = Path.GetDirectoryName(this.GetType().Assembly.Location) + "\\"; //获取程序集的加载路径
CurPaht.resultFilePaht = CurPaht.curPaht + "\\result.txt";
//加载后初始化的程序放在这里 这样程序一加载DLL文件就会执行
Document doc = Application.DocumentManager.MdiActiveDocument;
doc.Editor.WriteMessage("\n 加载程序中......");
RibbonControl ribbonCtrl = ComponentManager.Ribbon; //获取cad的Ribbon界面
RibbonTab tab = ribbonCtrl.AddTab("插件", "Acad.RibbonId1", true); //给Ribbon界面添加一个选项卡
RibbonPanelSource panelSource = tab.AddPanel("计算"); //给选项卡添加面板
panelSource.Items.Add(RibbonButtonInfos.LineBtn); //添加直线命令按钮
doc.Editor.WriteMessage("\n 成功添加菜单栏!");
}
}
}
其他代码:
using Autodesk.Windows;
using System;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace caculate_projected_area
{
public class RibbonButtonEX : RibbonButton
{
//正常显示的图片
private string imgFileName = "";
public string ImgFileName
{
get { return imgFileName; }
set { imgFileName = value; }
}
//鼠标进入时的图片
private string imgHoverFileName = "";
public string ImgHoverFileName
{
get { return imgHoverFileName; }
set { imgHoverFileName = value; }
}
public RibbonButtonEX(string name, RibbonItemSize size, Orientation orient, string cmd)
: base()
{
this.Name = name;//按钮的名称
this.Text = name;
this.ShowText = true; //显示文字
this.MouseEntered += this_MouseEntered;
this.MouseLeft += this_MouseLeft;
this.Size = size; //按钮尺寸
this.Orientation = orient; //按钮排列方式
this.CommandHandler = new RibbonCommandHandler(); //给按钮关联命令
this.CommandParameter = cmd + " ";
this.ShowImage = true; //显示图片
}
public void SetImg(string imgFileName)
{
Uri uri = new Uri(imgFileName);
BitmapImage bitmapImge = new BitmapImage(uri);
this.Image = bitmapImge; //按钮图片
this.LargeImage = bitmapImge; //按钮大图片
this.imgFileName = imgFileName;
}
/// <summary>
/// 鼠标离开事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void this_MouseLeft(object sender, EventArgs e)
{
if (this.ImgFileName != "")
{
RibbonButton btn = (RibbonButton)sender;
string imgFileName = this.ImgFileName;
Uri uri = new Uri(imgFileName);
BitmapImage bitmapImge = new BitmapImage(uri);
btn.Image = bitmapImge; //按钮图片
btn.LargeImage = bitmapImge; //按钮大图片
}
}
/// <summary>
/// 鼠标进入事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void this_MouseEntered(object sender, EventArgs e)
{
if (this.ImgHoverFileName != "")
{
RibbonButton btn = (RibbonButton)sender;
string imgFileName = this.ImgHoverFileName;
Uri uri = new Uri(imgFileName);
BitmapImage bitmapImge = new BitmapImage(uri);
btn.Image = bitmapImge; //按钮图片
btn.LargeImage = bitmapImge; //按钮大图片
}
}
}
}
using Autodesk.Windows;
using System;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace caculate_projected_area
{
public static class RibbonButtonInfos
{
//直线按钮
private static RibbonButtonEX lineBtn;
public static RibbonButtonEX LineBtn
{
get
{
lineBtn = new RibbonButtonEX("计算斜坡投影面积", RibbonItemSize.Large, Orientation.Vertical, "CPA");
lineBtn.SetImg(CurPaht.curPaht + "Images\\slope.png");//设置按钮图片
//添加提示对象
RibbonToolTip toolTip = new RibbonToolTip();
toolTip.Title = "斜坡投影面积";
toolTip.Content = "计算斜坡投影面积";
toolTip.Command = "CPA";
toolTip.ExpandedContent = "根据高程和空间坐标,计算斜坡投影面积";
string imgToolTipFileName = CurPaht.curPaht + "Images\\slope1.png";
Uri toolTipUri = new Uri(imgToolTipFileName);
BitmapImage toolTipBitmapImge = new BitmapImage(toolTipUri);
toolTip.ExpandedImage = toolTipBitmapImge;
lineBtn.ToolTip = toolTip;
//鼠标进入时的图片
lineBtn.ImgHoverFileName = CurPaht.curPaht + "Images\\slope2.png";
return lineBtn;
}
}
}
}
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.Windows;
using System;
namespace caculate_projected_area
{
public class RibbonCommandHandler : System.Windows.Input.ICommand
{
//定义用于确定此命令是否可以在其当前状态下执行的方法。
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
// 定义在调用此命令时调用的方法。
public void Execute(object parameter)
{
if (parameter is RibbonButton)
{
RibbonButton btn = (RibbonButton)parameter;
if (btn.CommandParameter != null)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
doc.SendStringToExecute(btn.CommandParameter.ToString(), true, false, false);
}
}
}
}
}
using Autodesk.Windows;
using System.Windows.Controls;
namespace caculate_projected_area
{
public static partial class RibbonTools
{
/// <summary>
/// 添加Ribbon选项卡
/// </summary>
/// <param name="ribbonCtrl">Ribbon控制器</param>
/// <param name="title">选项卡标题</param>
/// <param name="ID">选项卡ID</param>
/// <param name="isActive">是否置为当前</param>
/// <returns>RibbonTab</returns>
public static RibbonTab AddTab(this RibbonControl ribbonCtrl, string title, string ID, bool isActive)
{
RibbonTab tab = new RibbonTab();
tab.Title = title;
tab.Id = ID;
ribbonCtrl.Tabs.Add(tab);
tab.IsActive = isActive;
return tab;
}
/// <summary>
/// 添加面板
/// </summary>
/// <param name="tab">Ribbon选项卡</param>
/// <param name="title">面板标题</param>
/// <returns>RibbonPanelSource</returns>
public static RibbonPanelSource AddPanel(this RibbonTab tab, string title)
{
RibbonPanelSource panelSource = new RibbonPanelSource();
panelSource.Title = title;
RibbonPanel ribbonPanel = new RibbonPanel();
ribbonPanel.Source = panelSource;
tab.Panels.Add(ribbonPanel);
return panelSource;
}
/// <summary>
/// 给面板添加下拉组合按钮
/// </summary>
/// <param name="panelSource"></param>
/// <param name="text"></param>
/// <param name="size"></param>
/// <param name="orient"></param>
/// <returns></returns>
public static RibbonSplitButton AddSplitButton(this RibbonPanelSource panelSource, string text, RibbonItemSize size, Orientation orient)
{
RibbonSplitButton splitBtn = new RibbonSplitButton();
splitBtn.Text = text;
splitBtn.ShowText = true;
splitBtn.Size = size;
splitBtn.ShowImage = true;
splitBtn.Orientation = orient;
panelSource.Items.Add(splitBtn);
return splitBtn;
}
}
}
namespace caculate_projected_area
{
public static class CurPaht
{
public static string curPaht = "";
public static string resultFilePaht = "";
}
}
自己写的计算代码,按照自己的需求去实现
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using Autodesk.AutoCAD.DatabaseServices;
using System.IO;
namespace caculate_projected_area
{
public class Caculate
{
[CommandMethod("CPA")]
public void CPA()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
int count = 0;
do
{
count++;
//获取第一个点
Point3d point1 = new Point3d();
PromptPointResult ppr1;
do
{
ppr1 = ed.GetPoint("\n 请选择第一个点");
if (ppr1.Status == PromptStatus.Cancel)
{
return;
}
} while (ppr1.Status != PromptStatus.OK);
point1 = ppr1.Value;
File.AppendAllText(@CurPaht.resultFilePaht, "\n 选择的第一个点:(" + point1.X + "," + point1.Y + "," + point1.X + ")");
//获取第二个点
Point3d point2 = new Point3d();
PromptPointResult ppr2;
do
{
ppr2 = ed.GetPoint("\n 请选择第二个点");
if (ppr2.Status == PromptStatus.Cancel)
{
return;
}
} while (ppr2.Status != PromptStatus.OK);
point2 = ppr2.Value;
File.AppendAllText(@CurPaht.resultFilePaht, "\n 选择的第二个点:(" + point2.X + "," + point2.Y + "," + point2.X + ")");
// 获取两个点之间的距离
double disstance = GetDistanceBetweenTwoPoints(point1, point2);
ed.WriteMessage("两个点之间的距离" + disstance);
File.AppendAllText(@CurPaht.resultFilePaht, "\n 两点之间的空间距离为:" + disstance);
File.AppendAllText(@CurPaht.resultFilePaht, "\n --------------------------------------------");
} while (true);
}
private double GetDistanceBetweenTwoPoints(Point3d point1, Point3d point2)
{
return (Math.Sqrt(Math.Pow((point1.X - point2.X), 2) + Math.Pow((point1.Y - point2.Y), 2) + Math.Pow((point1.Z - point2.Z), 2)));
}
}
}
备注:引入包,可以自己在CAD的安装目录下找,也可以用ObjectARX。
本Demo用的包:
最终效果展示: