最近要做一个cad文件的7参数坐标转换的程序,想基于cad进行二次开发,初次学习。
为了方便快捷开发,基于cad.net进行二次开发,网上查了很多资料,有基于acad等各种,总是遇到这样那样的问题,经过自己研究,最终选择了直接开发命令的方式进行开发,但有时候还是用到acad相关函数,比如将Docmuent转换为AcadDocument进行相关操作等
( Autodesk.AutoCAD.Interop.AcadDocument acadDoc = adoc.GetAcadDocument() as Autodesk.AutoCAD.Interop.AcadDocument;
acadDoc.SendCommand("zoom e\n");
)。
如果直接用document的SendStringToExecute执行cad命令,由于是异步的,需要等到动态库执行完成才执行命令,不满足我的要求,因此,转换为acad文档进行同步命令执行。
1、开发环境搭建
(1)vs版本:vs2015
(2)cad版本:cad2018
(3)cad.net开发包(2个,objectarx库和.net库):Autodesk_ObjectARX_2018_Win_64_and_32_Bit.sfx.exe,AutoCAD_2018_dotnet_wizards。
开发包可以网上找,也可以官网下载,官网地址为:
https://www.autodesk.com/developer-network/platform-technologies/autocad。
官网.net下载如下图(objectarx貌似需要注册才能下载,我是网上下载的,由于网上找的.net库老是不行,所以通过官网下载):
逐次安装以上软件,就可以进行开发了。
2、开发入门
安装完成后,打开vs,就可以新建cad.net的开发了。
在vs中新建项目,选择cad模板,如下图所示:
安装完cad.net才能在模板中选择autocad 2018 plugin in,.net框架选择4.6,完成后,就建立了一个cad插件程序。
新建完成后,主要有两个文件:
myCommands.cs写命令,myPlugin.cs设置插件相关信息。
(1)插件初始化(myPlugin.cs)
比如,我要在插件初始化时检查实际,并在完成后提示插件加载成功等消息,在myPlugin.cs的初始化函数void IExtensionApplication.Initialize()中添加如下代码:
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
MyCommands.isLinced = checkTime(2020, 7, 7);
if (MyCommands.isLinced)
{
ed.WriteMessage("\n加载 坐标转换成功!\n坐标转换命令:\n ZBSH\n\n\n");
load();
}
else
{
ed.WriteMessage("\n加载 坐标转换 失败!\n时间过期!!!!!!\n");
}
其中checkTime函数是我自己写的时间许可,检查完后根据需要提示相关信息。
void IExtensionApplication.Terminate()函数为插件退出执行的函数。
(2)命令编写(myCommands.cs)
在myCommands.cs中加入一个命令,比如新建dwg命令,
[CommandMethod("NewDwg", CommandFlags.Modal)]
public void NewDwg()
{
string tmppath = "acad.dwt";
DocumentCollection dcol = Application.DocumentManager;
Document adoc = dcol.Add(tmppath);
dcol.MdiActiveDocument = adoc;
}
这样在cad中输入“newdwg”命令即可实现新建dwg功能。
(3)执行命令
调试状态下直接F5运行程序(Debug模式),即可调试(通过cad模板新建的项目,已经将调试里面的启动外部程序设置为cad执行程序了,因此不需要自己设置)。
编译完成后,自动打开cad程序。
在cad中输入命令“netload”(每次启动都需要输入该命令,全局设置请百度),
选择生成目录下的dll文件,可显示信息,如下图所示:
然后输入“newdwg”命令,即可新建一个dwg文件。
部署时,通过release编译,加载方式也是一样,打开cad程序,先执行“netload”命令,加载dll文件,然后就可以输入相关命令了。
3、7参数坐标转换
我自己做了一个窗体,选择控制点进行坐标转换(具体转换程序百度)。
[CommandMethod("sh", "zbsh", "zbsh", CommandFlags.Modal | CommandFlags.UsePickSet)]
public void MyCommand() // This method can have any name
{
// Put your command code here
if (!checkLince())
{
return;
}
frmZBZH frm = new frmZBZH();
System.Windows.Forms.IWin32Window w = System.Windows.Forms.Form.FromHandle(Application.MainWindow.Handle);
frm.Show(w);
}
写转换代码就和.net写是一样的了。
private void transFromOneFile(string dwgFile, Transform7CSH tf, ref List
{
if (null == allNotSupported)
{
allNotSupported = new List
}
Autodesk.AutoCAD.ApplicationServices.DocumentCollection dcol = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;
Autodesk.AutoCAD.ApplicationServices.Document adoc = dcol.Open(dwgFile, false);
//dcol.MdiActiveDocument = adoc;
//dcol.MdiActiveDocument = adoc;
//dcol.MdiActiveDocument.LockDocument();
adoc.LockDocument();//必须锁定,否则 acTrans.GetObject利用OpenMode.ForWrite会出错
// adoc = dcol.MdiActiveDocument;
Database acCurDb = adoc.Database;
using (Transaction acTrans = acCurDb.TransactionManager.StartOpenCloseTransaction())
{
// Open the Block table for read
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for write
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
List
foreach (ObjectId asObjId in acBlkTblRec)
{
DBObject obj = acTrans.GetObject(asObjId, OpenMode.ForWrite);
bool ok = transformEntity(obj, acTrans, tf, onlyMove);
if (false == ok)
{
string strobj = obj.ToString();
if (false == notSupported.Contains(strobj))
{
notSupported.Add(strobj);
}
if (false == allNotSupported.Contains(strobj))
{
allNotSupported.Add(strobj);
}
}
}
if (notSupported.Count > 0)
{
txtmsg.AppendText(string.Format("文件\"{0}\"不支持的格式:\n", dwgFile));
txtmsg.AppendText(string.Join(";\n", notSupported));
txtmsg.AppendText("\n");
}
// Commit the changes and dispose of the transaction
acTrans.Commit();
}
// 缩放到视图,用这个才是同步执行
//Autodesk.AutoCAD.Interop.AcadApplication app = Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication as Autodesk.AutoCAD.Interop.AcadApplication;
//app.ActiveDocument.SendCommand("zoom e\n");
Autodesk.AutoCAD.Interop.AcadDocument acadDoc = adoc.GetAcadDocument() as Autodesk.AutoCAD.Interop.AcadDocument;
acadDoc.SendCommand("zoom e\n");
// adoc.SendStringToExecute("\003\003zoom\ne\n", false, true, true);//异步执行,需要等到执行完后才执行该命令
// 关闭
if (chkCloseDealedFile.Checked)
{
//adoc.SendStringToExecute("e\n", false, true, true);
adoc.CloseAndSave(adoc.Database.Filename);
adoc.Dispose();
acCurDb.Dispose();
}
}
其中transformEntity()函数,实现实体的坐标转换。
Transform7CSH类是我写的7参数转换的类。
运行界面如下图所示: