admin管理员组

文章数量:1604751

以项目实战讲解CAD的二次开发

  • 说明
  • 背景目的
  • 环境搭建
    • c++
    • 启动程序
  • 后续的框架构想
  • 总结

说明

这是我的第一个博客,之前也一直不敢写,本人能力有限,怕写错,误导一批新手。也很久没有较深入的开发ObjectARX了,最近一两年都在搞桌面客户端和服务端了。这次借疫情呆在家,公司也想做一个新项目之际,暂且先不管这项目能否批下来,又或者以后我还负不负责,希望此篇文章能开个好头。

背景目的

背景就不说了(后面有关项目或公司机密的都不会说明),说说目标吧,能够适应各种cad:AutoCAD、BricsCAD、中望、浩辰等等。每种cad都有自己的SDK,我们主要以两种为代表AutoCAD和BricsCAD来讲解。另外对于大型项目而言,底层开发语言优先选择C++,负责自定义实体和一些复杂算法。向上兼容C#、VB.Net等。整体程序目录应该如下:
程序主目录
sys目录下面的arx子目录

环境搭建

比较基础的关于ObjectARX的环境搭建,网上应该有很多资料,这里不赘述了。主要的就是去官网下载SDK和安装向导。记住安装向导C++和C#是分开的,这里附上一个链接,页面最底部应该就是向导了。ObjectARX和Wizards.msi
另外关于cad和visual studio的版本对应,可参照版本对应

c++

通过向导生成的工程后

  1. 变更编译选项,团队项目编译一定要进行统一,譬如Debug_R21、Release_R21等,同时说明Debug、Release和sdk版本。不过我用向导生成后,发现Debug和Release的预编译器是共用的,也就是说,改Release同时会更改Debug,这会给项目带来不便,有时我们需要在Debug的项目中输出一些临时信息。打开项目的.vcxproj文件,如下两行:
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(UseOfMfc)'=='Dynamic'">_AFXEXT;_ALLOW_RTCc_IN_STL;%(PreprocessorDefinitions)</PreprocessorDefinitions>

更改为:

 <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_WIN64;_AFXEXT;_ALLOW_RTCc_IN_STL%(PreprocessorDefinitions)</PreprocessorDefinitions>
 <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WIN64;_AFXEXT;_ALLOW_RTCc_IN_STL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

其实它本身这方面的工程文件配置很凌乱,Debug和Release全在一个ItemDefinitionGroup节点里面。这里我就给它重新改写了:

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_ARX21|x64'">
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_BRX21|x64'">
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_ARX21|x64'">
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_BRX21|x64'">
  </ItemDefinitionGroup>
  1. 需要把输入目录和中间临时目录改写到固定的路径,提交代码时记得别提交这些临时文件。
  2. 添加公共库和头文件、第三方库和头文件等
  3. 对于managed的项目(供调用),记得添加AdditionalUsingDirectories。这里我们使用了代码引用cad的dll文件,使用这种方法,会有下面问题:
  • 对于AutoCAD,先包含"arxHeaders.h",sdk会自动包含managed的部分接口,而这时<accoremgd.dll>等还未引用,导致编译失败。所以"arxHeaders.h"要放到后面。
  • 对于BricsCAD,是没有限制的,但我们依靠BRX自带的__BRX宏就不可用了,需要我们在预处理自己定义。
#ifdef __BRX
#include "arxHeaders.h"
#using <brxmgd.dll>
#using <td_mgd.dll>
#include "util/type_mgd_brx.h"
#else
#using <accoremgd.dll>
#using <acdbmgd.dll>
#using <acmgd.dll>
#include "arxHeaders.h"
#include "util/type_mgd_arx.h"
#endif

通过向导生成项目后

  1. 需要把输入目录和中间临时目录改写到固定的路径,提交代码时记得别提交这些临时文件。
  2. 引用改为程序相对目录的dll,“Copy Local"改为"false”。

启动程序

我们适配了多版本cad,那么我们应该也要有个启动器能够选择不同cad进行启动和自动加载arx插件。

  • 界面,采用了duilib这个库,网上有很多版本,这里附一个我认为比较通用小巧的duilib。当然也可以使用qt,我目前也在评估使用qt的好处和坏处,甚至是cad里面也在思考是否可用qt。
  • 自动加载,使用的是cad的自动加载机制。在arx子目录下面有加载文件,AutoCAD是ACAD.RX, BricsCAD的是autoload.rx。
    启动程序会通过注册表获取本机已经安装的cad版本,然后和程序已开发的cad版本进行匹配,显示到程序列表。

最后用户选择列表项启动后的过程:

  1. 添加对应cad支持搜索目录
  2. 启动对应cad
  3. 等待加载完成
  4. 按项目需要是否需要在卸载后自动清除支持目录。

后续的框架构想

  • 在线更新
  • 多语言,目前在外企,自然会有这种考虑。
  • 疫情常态,考虑数据云服务化
  • 每个人网络都会不同,云网络一旦出现问题,没有办法补救,所以还需要可离线操作。
  • 对于离线操作,可通过加密狗、加密文件解决。

总结

今天只介绍了一个项目的大概思路,下一章开始进行公共库应该怎么设计和一些通用功能的实现。

本文标签: 实战项目cad