当前位置:   article > 正文

【 以项目实战讲解CAD的二次开发(二)】_cad二次开发 c++ 实战源码

cad二次开发 c++ 实战源码


网上关于cad的开发项目几乎是没有,相关技术文章也少得可怜。一方面是因为cad的开发基本是和工程项目或者企业产品深度结合的一个路线,所以源码就是整个企业的核心根本,在很多企业中都已经是使用物理锁把开发电脑锁住,以防泄露。另一方面cad开发的发展方向太窄,看看现如今互联网人潮汹涌,前赴后继,薪资也是相差甚大。
当然“开发只是一种手段,语言只是一门工具”,这句话很多人都说过,也的确正确。但我认为这句话只有你足够优秀,真的有能力在各种语言中驾轻就熟才显得不那么虚。因此每个人初期还是踏踏实实走好自己的每一步。基础扎实之后,无论走什么路线,都是比较轻松地。

基础库

一个软件公司里面都有自己的通用库,它主要分为全产品通用和类似产品通用。
  • 1
  • base
  • acad
  • project
    base可以定义为全产品通用的api,主要接口有string、file、thread、database、md5等等基础api,要尽量保证平台无关性。
    acad顾名思义只cad相关的库,可依据功能性进行分类和封装api。譬如xdata、layer、dbentity、sysvar、acgs、acge、acui等等。
    project是本项目中的通用接口,比如命令的统一注册、数据的统一获取设置等等。

数据层

数据当然是项目或产品的重中之重,总体而言cad的数据中可分为外观、工程量。

自定义实体

在这里插入图片描述
自定义实体主要是为了数据安全、更为复杂的交互等而设计。通常我们都会以继承AcDbEntity而设计。在一个产品中,我们必须做个产品虚基类实体。比如DaveEntity,然后从该实体继承我们其他有意义的实体。它主要用来记录一些通用数据和方便我们做程序处理的。
OMF的设计上BricsCAD在sdk上提供了C++的类,而AutoCAD还是主要以COM的形式提供。有时感慨AutoDesk不思进取,估计力量都投到Revit或其他产品上面去了。从这里看一看出BricsCAD非常适合C++开发,从Ribbon、OMF都提供了接口。

工程量数据

这和具体业务相关,也较为简单,总之一切要以生成报表预算为准则去设计。

数据提供者

包括用户、工程量、权限、单价等各种数据的提供通常是数据库,由于这里不考虑直连,之前也分析过要离线设计,所以分为网络、和本地加密文件(或加密狗)两种方式。在设计框架的时候就要考虑数据提供的问题。

template<IProvider::ModelType type,typename TProvider = IProvider>
class DataProviderBase
{
public:
DataProviderBase() : type_(type), provider_(nullptr) {
static_assert(std::is_base_of<IProvider, TProvider>::value, "provider type error");
}
virtual ~DataProviderBase() = default;
public:
	virtual IProvider::ModelType GetModelType() const {
		return type_;
	}
	virtual IProvider* GetProvider()
	{
		if (provider_== nullptr)
		{
			provider_= dynamic_cast<TProvider *>(CreateProvider());
			if (provider_!= nullptr)
				provider_->SetPlugin(this);
		}				
		return provider_;
	}
protected:
	virtual CContainerUI* CreateProvider() = 0;
protected:
 IProvider::ModelType type_;
 TProvider* provider_;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

网络

数据提供者网络部分的实现,大概如下:

class UserCloudProvider : public IProvider
{
public:
UserCloudProvider() : type_(kDataFromCloud){
}
~UserCloudProvider() = default;
protected:
ModelType type_;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

本地加密文件

数据提供者本地部分的实现,大概如下:

class UserLocalProvider : public IProvider
{
public:
UserLocalProvider () : type_(kDataFromLocal){
}
~UserLocalProvider () = default;
protected:
ModelType type_;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这些源码只 进行思路分析。另外本地文件加密要慎之又慎,需要多重加密以确保安全。

外观

“芙蓉不及美人妆,水殿风来珠翠香”。外观就是把各种数据展示给客户,精确且惊艳为最佳。
  • 1

Ribbon菜单

在这里插入图片描述
Ribbon的实现在AutoCAD例子中基本都是.Net源码,而在BricsCAD的官方例子中则是使用了C++接口。我们可以统一成.Net功能,但BricsCAD中可能加载较慢,影响体验,所以还是统一成C++。有关Ribbon的C#核心代码(网上例子超多,这里还是要充分考虑别用明确的AutoDesk.AutoCAD命名空间,因为我们还要支持其他CAD呢):

// 声明需要添加的Ribbon Tab页
_AcWnd1.RibbonControl ribbonControl = _AcWnd1.ComponentManager.Ribbon;
_AcWnd1.RibbonTab Tab = new _AcWnd1.RibbonTab();
Tab.Title = "蚺城疯子软件";
Tab.Id = "RibbonTest_ID";
ribbonControl.Tabs.Add(Tab);
// 创建新的Panel
var panel1Panel = new _AcWnd1.RibbonPanelSource();
panel1Panel.Title = "图层管理";
var Panel1 = new _AcWnd1.RibbonPanel();
Panel1.Source = panel1Panel;
Tab.Panels.Add(Panel1);
// 添加按钮到Panel中
string ribbon_path = MyMgd.Utils.GetStartPath() + @"skin\image\ribbon\";
Bitmap img1_16 = new Bitmap(ribbon_path + "button1_16.png"),
	img1_32 = new Bitmap(ribbon_path + "button1_32.png"),
    img2_16 = new Bitmap(ribbon_path + "button2_16.png"),
    img2_32 = new Bitmap(ribbon_path + "button2_32.png");
var pan1btnAddLayers = NewRibbonButton("添加图层", "AddLayer ", img1_16, img1_32);
var pan1btnEraseLayers = NewRibbonButton("允许导出", "Export ", img2_16, img2_32);

var pan1row1 = new _AcWnd1.RibbonRowPanel();
pan1row1.Items.Add(pan1btnEraseLayers);
pan1row1.Items.Add(new _AcWnd1.RibbonRowBreak());

panel1Panel.Items.Add(pan1btnAddLayers);
panel1Panel.Items.Add(new _AcWnd1.RibbonSeparator());
panel1Panel.Items.Add(pan1row1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

停靠面板

在这里插入图片描述
一般是停靠在左侧,如天正系列的设计软件。在开发过程中还需要考虑高DPI的支持,由于我屏幕是2.5K,所以天正的字体在我这里会显得很小,或许客户的屏幕是4K,那估计就小得没法正常操作了。之后的交互UI同样要注意高分辨率屏幕的问题。

交互UI

一个项目中,使用到的界面会非常的多,我们要事先考虑那些是共有的,提出来,我们事先做好UI的拆分。譬如列表格式、表格样式、属性界面等等。
  • 1

CAD预览控件

在这里插入图片描述
预览控件其实也是交互UI的一种,但实现方式多种多样,可简可繁,下一章将会详细讨论。复杂功能应当有如下:

  • 左右键、双击事件
  • 可支持图纸、块、实体、临时实体等预览
  • 可缩放、拖拽等cad简易操作,以实现用户仔细确认。
  • 分页

总结

  1. 部分功能在AutoCAD和BricsCAD上的实现方式不同,应尽量统一——OMF,Ribbon
  2. 界面需要注意高DPI的问题
  3. 数据和ui耦合性尽量要降低,另外本地加密问题

基础库或者基础框架总是要有人使用才会丰富、进化而变得更为实用,本章只提供大概思路。一个好的通用库可以大大的提升团队的开发 效率。
这些框架的东西没怎么细讲,否则每个环节都要花大篇幅的设计和源码,那就失去了重点。
之后就是每个具体功能的详细记录、分析、探讨——预览控件,从C++和C#、AutoCAD和BricsCAD多个方面来讨论。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/40346
推荐阅读
相关标签
  

闽ICP备14008679号