从0开始——CAD与Tekla开发入门

背景

因工作需要,想尝试一下从autoCAD读取图纸数据,并直接在Tekla Structures建模。之前有使用过VS2010,用vb.net和c#.net开发过一点程序,这次想继续用VS2010进行开发。由于将要从0开始学习CAD和Tekla两款软件的二次开发,等完成后,对其他人也有些参考价值,所以本文将记录下整个的摸索过程。
目前的大致思路是:
- 通过CAD插件读取数据
- 储存原始数据
- 原始数据经过计算后,生成模型参数数据
- 通过Tekla插件将模型绘制出来


尝试过程

2016.08.23

第1步目标:外部程序调用Tekla的API,在模型里绘制简单图形(已实现)

目前已实现,稍后补上。

第2步目标:外部程序调用autoCAD的API,在图纸上绘制简单图形(已实现)

经过搜索,发现CAD二次开发主分为:VBA、Lisp、ObjectARX和.Net。从我的开发经历看,.Net应该是最满足项目需求的——操作体验与保密,所以首先尝试.Net的方案。
我用的是autoCAD2014,找到这篇文章AutoCAD .NET API二次开发学习指南
去到autoCAD官网的资料区,里面有各种文档和安装程序,可惜没有找到中文网页。
之前搜索ObjectARX时,有下载2014版的SDK,是在新浪博客找到的,链接也是官网的。
从资料区看,autoCAD2014支持VS2010和VS2012,看来运气还不错。
安装完ObjectARX SDK,确切地说是解压了之后,在VS2010里并没有出现ObjectARX的模板。于是按照学习指南的步骤,又安装了.NET Wizards,程序是直接在官网下载的。在安装.NET Wizards之前,我还安装了ObjectARX Wizards,同样是在官网找到的。ObjectARX Wizards安装了之后,在VS2010里C++下出现了AutoCAD的模板,安装.NET Wizards之后,才在C#下出AutoCAD的模板。
C#下的新模板
新建了一个工程,里面已经添加了autoCAD的一些引用,直接编译,没有报错。
这里写图片描述
生成的是.dll文件,不能直接运行,我又另外新建了一个普通工程TestModel,想添加引用,看能不能编译通过。因为dll的插件里是空的,我想起了之前在github下载的一个cad 插件工程,当时已经编译通过生成了dll文件。于是,我用它来测试引用,顺便看看能不能操作autoCAD。
我先是只添加了dll的引用和using声明,编译通过,但运行时报错:”未能加载文件或程序集“Acdbmgd.dll”或它的某一个依赖项。找不到指定的模块。“。添加对Acdbmgd.dll等几个文件的引用,还是报错。
这里写图片描述
还是看文档吧,下载了AutoCAD 2014 .Net Training,里面有个PPT,英文的。看了几页,惊呆了!居然是用netload加载dll到autoCAD!试了一下,顺利地运行了一个画直线的命令,果然是打开的方式不对。可是,这种用法,真的不符合我的预期啊!
这里写图片描述
但我不死心,继续找。终于找到《外部.NET程序与AutoCAD交互》,在TestModel中添加了“AutoCAD 2014 Type Library”引用,但添加”using Autodesk.AutoCAD.Interop;“时提示错误。搜索“”,找到一个帖子,以下一个回答。

晕,还没有人回答你噢,我来说一下吧,首先第一步你要添加两个COM引用:
AutoCAD 2010 Type Library //我的机子里装的是CAD2010版
AutoCAD/ObiectDBX Common 18.0 Type Library
把这两个引用的命名空间引进来
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
//就可以写代码了
AcadApplication CadApp; //定义一个CAD应用程序对像
AcadDocument CadDoc; //定义一个CAD文档
AcadModelSpace CadSpace; //这是CAD的模型空间
//然后就先一个CAD应用程序
CadApp = new AcadApplication();
CadApp.Visible = true; //如果你想把CAD显示到前台来,就设为true
CadDoc = CadApp.ActiveDocument; //获取CAD当前活动的文档
CadSpace = (AcadModelSpace)CadDoc.ModelSpace; //获得命名空间
double[] c = new double[6]; //我随便定义一个要画线的点数组,记得点这个数组里是按XYZ坐标顺序存放的噢
c[0] = 34; c[1] = 98; c[2] = 67; c[3] = 956; c[4] = 655; c[5] = 322; //随便输的
CadSpace.Add3DPoly(c); //我这里画的是三维多段线,你要画其它的线型的话,到找一下对应的方法即可。
别忘了记得给分噢!

但还是提示错误,我用Everything搜索“Autodesk.AutoCAD.Interop.dll”,在ObjectARX SDK里找到了这个文件,有32位、64位两种,还看到了Autodesk.AutoCAD.Interop.Common.dll,我引用了64位的这两个文件,错误消除了。直接编译运行,成功打开了一个新autoCAD进程,画出了一条线。
这里写图片描述
这里写图片描述
这里写图片描述

在《外部.NET程序与AutoCAD交互》找到调用已打开autoCAD的代码,修改后如下,也成功地在autoCAD里画了一条线。后来发现,只添加两个dll,不添加COM引用,也是可以的。

        private void button2_Click(object sender, EventArgs e)
        {
            const string progID = "AutoCAD.Application.19.1"; 
            AcadApplication acApp = null; 
            try 
            { 
                acApp = (AcadApplication)Marshal.GetActiveObject(progID); 
            }catch{
                try { 
                    Type acType = Type.GetTypeFromProgID(progID); 
                    acApp = (AcadApplication)Activator.CreateInstance(acType, true); 
                } catch { 
                    MessageBox.Show("Cannot create object of type \"" + progID + "\""); 
                } 
            }
            if (acApp != null){ 
                // By the time this is reached AutoCAD is fully  
                // functional and can be interacted with through code   
                acApp.Visible = true;
                AcadDocument CadDoc;  //定义一个CAD文档
                AcadModelSpace CadSpace;  //这是CAD的模型空间
                //然后就先一个CAD应用程序
                acApp.Visible = true;  //如果你想把CAD显示到前台来,就设为true
                CadDoc = acApp.ActiveDocument;  //获取CAD当前活动的文档
                CadSpace = (AcadModelSpace)CadDoc.ModelSpace; //获得命名空间
                double[] c = new double[6];  //我随便定义一个要画线的点数组,记得点这个数组里是按XYZ坐标顺序存放的噢
                c[0] = 34; c[1] = 98; c[2] = 67; c[3] = 956; c[4] = 655; c[5] = 322;  //随便输的
                CadSpace.Add3DPoly(c);
                MessageBox.Show("hello");
            }
        }

现在能启动autoCAD了,后面就是想办法把插件dll加载进去。

第3步目标:外部程序调用autoCAD .Net API(未实现)

第2步完成的,其实是通过COM方式操作的autoCAD。《外部.NET程序与AutoCAD交互》虽然写了怎样加载.Net程序集来调用.Net API,但一直出现应用程序加载失败。看来事情并不是那么简单。COM方式操作autoCAD难以得到返回值,而我的目标是读取数据。
看来这条路暂时不通,调整目标:用acad2014.lsp自动加载dll插件,通过插件与外部程序通讯。

C:\Program Files\Autodesk\AutoCAD 2014\Support\acad2014.lsp
(COMMAND "NetLoad" "D:\\test.dll")

2016.08.24

第4步目标:用.Net插件在图纸上画常用图形、标注等(部分实现)

先看《AutoCAD 2014 .Net Training》里的教程,把里面的示例工程都认真看了一遍。从1到8,每个示例添加一点功能,发现它把常用的功能都演示了下:画圆、画块、database、Jigs、PointMonitor、添加右键、添加窗体。可惜没说Ribbon,我找到AutoCAD中程序创建Ribbon界面执行AutoCAD命令,本想直接添加到示例8,但引用老是有问题。然后,我用Wizard新建了个工程,引用全部选中,把代码复制进去,又添加System.Xaml引用和using Autodesk.Windows;终于编译通过,创建出了一个空白Ribbon Tab。

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

using Autodesk.Windows;

        private const string MY_TAB_ID = "MY_TAB_ID";

        [CommandMethod("addMyRibbon")]
        public void createRibbon()
        {
            Autodesk.Windows.RibbonControl ribCntrl =
                      Autodesk.AutoCAD.Ribbon.RibbonServices.RibbonPaletteSet.RibbonControl;
            //can also be Autodesk.Windows.ComponentManager.Ribbon;     

            //add the tab
            RibbonTab ribTab = new RibbonTab();
            ribTab.Title = "My custom tab";
            ribTab.Id = MY_TAB_ID;
            ribCntrl.Tabs.Add(ribTab);

            //create and add both panels
            addPanel1(ribTab);
            addPanel2(ribTab);

            //set as active tab
            ribTab.IsActive = true;
        }

        private void addPanel2(RibbonTab ribTab)
        {
        }

        private void addPanel1(RibbonTab ribTab)
        {
            //throw new NotImplementedException();
        }

这里写图片描述
这里写图片描述
这里写图片描述
当我想继续添加Panel和Button时,又出现引用问题了,有一个类的声明老找不到。

2016.08.25

折腾了半天,发现是自定义的。。。补上之后,终于添加上按钮了。

//添加按钮的代码
        private void addPanel2(RibbonTab ribTab)
        {
            //create the panel source
            RibbonPanelSource ribPanelSource = new RibbonPanelSource();
            ribPanelSource.Title = "Edit Registry";

            //create the panel
            RibbonPanel ribPanel = new RibbonPanel();
            ribPanel.Source = ribPanelSource;
            ribTab.Panels.Add(ribPanel);

            //create button1
            RibbonButton ribButtonDrawCircle = new RibbonButton();
            ribButtonDrawCircle.Text = "My Draw Circle";
            ribButtonDrawCircle.ShowText = true;
            //pay attention to the SPACE after the command name
            ribButtonDrawCircle.CommandParameter = "DrawCircle ";
            ribButtonDrawCircle.CommandHandler = new AdskCommandHandler();
            ribPanelSource.Items.Add(ribButtonDrawCircle);
        }

        private void addPanel1(RibbonTab ribTab)
        {
            //throw new NotImplementedException();
        }
        [CommandMethod("DrawCircle")]
        public void DrawCircle()
        {
            //画个圆,实现在此略去,这不是这篇blog的重点。
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            PromptPointOptions getPointOptions = new PromptPointOptions("Pick Center Point : ");
            PromptPointResult getPointResult = ed.GetPoint(getPointOptions);
            if ((getPointResult.Status == PromptStatus.OK))
            {
                PromptDistanceOptions getRadiusOptions = new PromptDistanceOptions("Pick Radius : ");
                getRadiusOptions.BasePoint = getPointResult.Value;
                getRadiusOptions.UseBasePoint = true;
                PromptDoubleResult getRadiusResult = ed.GetDistance(getRadiusOptions);
                if ((getRadiusResult.Status == PromptStatus.OK))
                {
                    Database dwg = ed.Document.Database;
                    Transaction trans = dwg.TransactionManager.StartTransaction();
                    try
                    {
                        Circle circle = new Circle(getPointResult.Value, Vector3d.ZAxis, getRadiusResult.Value);
                        BlockTableRecord btr = (BlockTableRecord)trans.GetObject(dwg.CurrentSpaceId, OpenMode.ForWrite);
                        btr.AppendEntity(circle);
                        trans.AddNewlyCreatedDBObject(circle, true);
                        trans.Commit();
                    }
                    catch (System.Exception ex)
                    {
                        ed.WriteMessage("problem due to " + ex.Message);
                    }
                    finally
                    {
                        trans.Dispose();
                    }
                }
            }
        }
//以下是响应按钮的自定义类
    class AdskCommandHandler : System.Windows.Input.ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            //is from Ribbon Button
            RibbonButton ribBtn = parameter as RibbonButton;
            if (ribBtn != null)
            {
                //execute the command 
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute((string)ribBtn.CommandParameter, true, false, true);
            }
        }
    }

这里写图片描述
这一部分的工程代码到此处可下载

第5步目标:把ribbon、窗体、右键整合到同一个插件工程(已实现)

2016.08.26
把Ribbon、palette、右键的代码整合到一起之后,可以通过命令来加载它们了。但为了方便,我想让CAD启动时,自动加载。

        void IExtensionApplication.Initialize()
        {
            AddContextMenu();
            createRibbon(); 
            palette();
         }

        void IExtensionApplication.Terminate()
        {
            RemoveContextMenu();            
        }

按理说,上面的代码就能让CAD在启动时加载右键、Ribbon、窗体了,但Dll加载却出问题了。逐一测试后,发现是Ribbon加载有问题。在《 打开cad如何自动加载ribbon菜单》找到了答案,原来是要等待Ribbon启动。原样复制代码,却提示“No overload for ‘ComponentManager_ItemInitialized’ matches delegate ‘System.EventHandler’”。还好最后找到另一篇《获取Ribbon 选项卡(Tab)被点击的消息》,添加了一个“< RibbonItemEventArgs >”,错误消除。

        void IExtensionApplication.Initialize()
        {
            AddContextMenu();
            Autodesk.Windows.ComponentManager.ItemInitialized += new EventHandler<RibbonItemEventArgs>(ComponentManager_ItemInitialized); 
            palette();
         }

        void IExtensionApplication.Terminate()
        {
            RemoveContextMenu();
        }
        void ComponentManager_ItemInitialized(object sender, RibbonItemEventArgs e)
        {
            if (Autodesk.Windows.ComponentManager.Ribbon != null)
            {
                createRibbon();
                Autodesk.Windows.ComponentManager.ItemInitialized -= new EventHandler<RibbonItemEventArgs>(ComponentManager_ItemInitialized);
            }
        }

这里写图片描述
自动加载使用的是注册表法,为了不让CAD提示警告,还把dll放在了CAD安装目录下。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R19.1\ACAD-D001\Applications\CadDataCapture]
"LOADCTRLS"=dword:0000000e
"LOADER"="C:\\Program Files\\Autodesk\\AutoCAD 2014\\CadDataCapture.dll"
"DESCRIPTION"="AutoCAD Data Capture"
"MANAGED"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R19.1\ACAD-D001\Applications\CadDataCapture\Commands]
"palette"="CadDataCapture.resources.dll#palette"

[HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R19.1\ACAD-D001\Applications\CadDataCapture\Groups]
"CadDataCapture_CMDS"="CadDataCapture_CMDS"

但还有一个问题,就是palette加载之后,重启CAD,会有两个palette。这个小问题就不纠结了,这个目标算是完成了。
这部分的工程代码可在此处下载

暂告一段落

后面的开发研究就不具备普遍性了,所以文章就暂告一段落,一些工程代码随后上传。

  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: ObjectARX Wizards是一种用于AutoCAD 2024的开发工具,它可以帮助开发人员创建自定义的AutoCAD应用程序和插件。ObjectARX是一种编程接口,允许开发人员使用C++语言来扩展AutoCAD的功能。 通过使用ObjectARX Wizards,开发人员可以轻松地创建与AutoCAD 2024兼容的定制应用程序。该工具提供了一系列的模板和向导,使开发人员可以快速开始开发过程。模板包括各种AutoCAD对象的定义,如线条、圆、块等,开发人员可以根据自己的需求进行定制。 ObjectARX Wizards还提供了易于使用的界面,用于设置应用程序的属性和选项。开发人员可以通过简单的界面设置插件的名称、版本号、帮助文件路径等信息。此外,工具还提供了一些可自定义的选项,以便开发人员根据自己的需求设置插件的行为。 ObjectARX Wizards还提供了丰富的文档和示例代码,以帮助开发人员学习和理解如何使用ObjectARX进行开发开发人员可以参考示例代码,并使用文档提供的说明进行自定义开发。这些文档详细解释了ObjectARX的各个方面,包括对象模型、命令定义、界面交互等。 总而言之,ObjectARX Wizards是一种强大的工具,可帮助开发人员在AutoCAD 2024中创建定制的应用程序和插件。它提供了丰富的模板、向导、界面和文档,以帮助开发人员快速开始开发,并为他们提供了使用ObjectARX进行扩展的所有必要资源。 ### 回答2: ObjectARX Wizards是用于AutoCAD 2024开发的工具。ObjectARX是AutoCAD开发平台,允许开发者创建自定义的AutoCAD应用程序和插件。而ObjectARX Wizards是一个辅助工具,可以帮助开发者更快速地创建ObjectARX项目。 使用ObjectARX Wizards,开发者可以自动生成一个基本的ObjectARX项目框架,包括一些基本的代码和文件结构。这样,开发者可以直接在生成的项目中进行代码编写,而无需从头开始创建一个完整的项目。 ObjectARX Wizards提供了多个模板,可以根据开发需求选择相应的模板来生成项目。例如,可以选择创建一个简单的插件,或者选择创建一个复杂的应用程序。生成项目后,开发者可以根据自己的需要添加更多的功能和代码。 除了生成项目框架外,ObjectARX Wizards还提供了一些额外的功能和工具,帮助开发者更好地理解和使用ObjectARX平台。例如,它包含了一些示例代码和教程,可以帮助开发者学习如何使用ObjectARX进行开发。此外,它还提供了一些调试和测试工具,用于帮助开发者调试和测试他们的应用程序。 总之,ObjectARX Wizards是一个方便的工具,可以帮助开发者更快速地创建和开发自定义的AutoCAD应用程序和插件。它提供了项目框架的自动生成功能,以及一些额外的功能和工具,帮助开发者更好地进行开发和调试。对于AutoCAD 2024的开发者来说,ObjectARX Wizards无疑是一个重要的工具和资源。 ### 回答3: ObjectARX Wizards for AutoCAD是一套用于AutoCAD 2024开发的工具包。AutoCAD是一种重要的CAD软件,用于创建、编辑和查看2D和3D设计。ObjectARX Wizards为开发者提供了一系列的向导和模板,帮助他们快速创建自定义的AutoCAD插件和应用程序。 使用ObjectARX Wizards,开发者可以利用AutoCAD的强大功能来满足个性化需求。通过向导和模板,开发者可以轻松创建命令、自定义对象和图元等。他们可以基于已有的AutoCAD功能,创建新的工具,为用户提供更高效的设计和编辑体验。 ObjectARX Wizards还提供了一系列的示例代码,帮助开发者理解和学习如何使用ObjectARX进行AutoCAD插件和应用程序的开发。通过这些示例代码,开发者可以了解如何与AutoCAD的对象模型交互,如何处理用户输入和命令,以及如何实现自定义的图形绘制和编辑功能。 ObjectARX Wizards为开发者提供了强大的开发工具,使其能够更好地利用AutoCAD的功能,开发出个性化的插件和应用程序,满足用户的特定需求。无论是绘图工具、数据处理工具还是自动化工具,开发者都可以利用ObjectARX Wizards为AutoCAD 2024创建高效且功能丰富的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值