当前位置: 首页 > news >正文

29 中望CAD二次开发(ZRX C++)-Overrule

目录

29.1 简单的例子

29.2 ZcGiDrawableOverrule


回顾《22 中望CAD二次开发(ZRX C++)-自定义实体》这一节,我们通过派生ZcDbCurve,实现了自定义实体。自定义实体允许开发者自定义实体行为,例如绘制、几何变换、捕捉等。如果我们不想重写实体类型,只是想改变原生实体类型的行为,可以用到Overrule。所以本讲介绍Overrule的用法。

29.1 简单的例子

前面自定义实体实现了在多段线的每个节点上绘制一个圆,如下图所示:

这里用Overrule实现上面的效果。想要实现自定义绘制行为,需要派生一个类,叫做ZcGiDrawableOverrule,它的父类是ZcRxOverrule,实际上,各种Overrule的父类都是ZcRxOverrule。下面一步步实现:

第一步:创建一个ZcGiDrawableOverrule的派生类:

class MyLineOverrule :public ZcGiDrawableOverrule { };

第二步:重写父类虚函数

这里需要重写两个虚函数,一个是worldDraw,就是在这个函数里头重写绘制行为;另一个需要重写的是isApplicable,这个函数来自ZcRxOverrule,是一个抽象函数,也就是说,它是必须要实现的,后面介绍它的用法。

class MyLineOverrule :public ZcGiDrawableOverrule { public: virtual ZSoft::Boolean worldDraw( ZcGiDrawable* pSubject, ZcGiWorldDraw* wd) override { ZcDbLine* line = ZcDbLine::cast(pSubject); if (line) { ZcGePoint3d startp = line->startPoint(); ZcGePoint3d endp = line->endPoint(); wd->geometry().circle(startp, 10, ZcGeVector3d::kZAxis); wd->geometry().circle(endp, 10, ZcGeVector3d::kZAxis); } return ZcGiDrawableOverrule::worldDraw(pSubject, wd); } virtual bool isApplicable(const ZcRxObject* pOverruledSubject) const { return ZSoft::kTrue; } };

上面重写的方法worldDraw实现了自定义绘制行为。pSubject就是该规则作用的实体,这里把它转成目标对象ZcDbLine,然后利用ZcGiWorldDraw::geomtry().circle()函数在直线端点上绘制圆,实现我们想要的效果。

问题:ZcGiDrawable可以是其他类型的实体吗?答案:不是。因为该规则作用在什么实体类型上,是我们显式指定的,也必须要指定。所以才有下一步的操作。

第三步:添加移除自定义行为

可以在插件加载的时候安装,在插件卸载的时候移除:

static MyLineOverrule mylineOverrule; void initapp() { ZcRxOverrule::addOverrule(ZcDbLine::desc(), &mylineOverrule, false); } void unloadapp() { ZcRxOverrule::removeOverrule(ZcDbLine::desc(), &mylineOverrule); }

观察addOverrule这个方法,它需要通过第一个参数指定实体类型,这里指定ZcDbLine,也就是说所有的ZcDbLine都将使用这个自定义的绘制规则。

第四步:编译运行

加载插件后,绘制直线,会自动在线的端点上出现圆。

问题:加载插件后,对于重新绘制的LINE起作用,对原有的图形是否起作用?答案:起作用,但是需要重绘,也就是调用REGEN命令。也可以在初始化插件的时候,由程序实现重绘:

void initapp() { ZcRxOverrule::addOverrule(ZcDbLine::desc(), &mylineOverrule, false); //重生成 zcedRegen(); }

29.2 ZcGiDrawableOverrule

29.1通过ZcGiDrawableOverrule介绍了Overrule的基本用法,对于ZcGiDrawableOverrule还有其他几个用法。

(1)设置过滤

29.1实现的规则对所有的LINE都起作用,可以通过重写isApplicable来设置过滤条件。下面演示,只对固定图层的LINE起作用:

virtual bool isApplicable(const ZcRxObject* pOverruledSubject) const override { ZcDbEntity* ent = ZcDbEntity::cast(pOverruledSubject); if (ent) { ZTCHAR* layerNanme = ent->layer(); if (_tcsicmp(layerNanme, _T("0")) == 0) { return ZSoft::kTrue; } } return ZSoft::kFalse; }

也就是说返回false规则不起作用,返回true起作用。

(2)设置属性

通过重写setAttributes可以对规则起作用的实体设置属性,例如设置颜色:

virtual ZSoft::UInt32 setAttributes( ZcGiDrawable* pSubject, ZcGiDrawableTraits* traits) override { auto flags = ZcGiDrawableOverrule::setAttributes(pSubject, traits); ZcDbLine* line = ZcDbLine::cast(pSubject); if (line) { traits->setColor(5); } return flags; }

注:这里设置的属性只会影响到图形的外观,并没有真的改变它的颜色。

问题:如果设置图层会怎么样?

virtual ZSoft::UInt32 setAttributes (ZcGiDrawable* pSubject, ZcGiDrawableTraits* traits) override { auto flags = ZcGiDrawableOverrule::setAttributes(pSubject, traits); ZcDbLine* line = ZcDbLine::cast(pSubject); if (line) { ZcDbLayerTable* layerTable; zcdbHostApplicationServices()->workingDatabase()->getLayerTable(layerTable); ZcDbObjectId layerObjId; layerTable->getAt(_T("ss"), layerObjId); //设置图层 traits->setLayer(layerObjId); } return flags; }

看下图,虽然设置了名为ss的图层,但是看它的属性仍然是0层。这种规则的设置,只会影响外观,不会改变图形本身的属性。所谓影响外观,例如,该图形的颜色是随层的,设置了它的图层是ss层,而ss层的颜色是红色的,所以看图形的颜色也是红色的。同时,改变ss图层的显隐也会影响到下面的图形,虽然它本质上不在ss层。

(3)视口绘制

通过重写viewportDraw方法,实现不同视口的重绘:

virtual void viewportDraw(ZcGiDrawable* pSubject, ZcGiViewportDraw* vd) override { ZcDbLine* line = ZcDbLine::cast(pSubject); if (line) { struct resbuf rb; zcedGetVar(_T("CVPORT"), &rb); if (rb.resval.rint == 2) { vd->subEntityTraits().setColor(1); ZcGePoint3d startp = line->startPoint(); ZcGePoint3d endp = line->endPoint(); ZcGePoint3d pts[2] = { startp,endp }; vd->geometry().polyline(2, pts); } else { vd->subEntityTraits().setColor(5); ZcGePoint3d startp = line->startPoint(); ZcGePoint3d endp = line->endPoint(); ZcGePoint3d pts[2] = { startp,endp }; vd->geometry().polyline(2, pts); } } }

上面代码实现,在编号为2的视口绘制的线的颜色索引为1,其他视口绘制的线的颜色索引为5:

注:如果要重写viewportDraw,需要让worldDraw返回false。

除了ZcGiDrawableOverrule,还有很多其他类型的Overrule,如下图,实现步骤都一样,这里就不赘述了。

http://www.jsqmd.com/news/550530/

相关文章:

  • 一站式员工福利平台靠谱选型:技术落地逻辑与核心要点拆解
  • 5分钟上手Python股票数据接口:MOOTDX让金融分析如此简单
  • 效率提升秘籍:基于快马AI生成自动化脚本,十分钟搞定百个页面每日巡检
  • 牛行为识别数据集(5000张图片已划分、已标注)AI训练适用于目标检测任务
  • 为什么Ag比grep快10倍?深入解析Ag搜索工具的性能优化技巧
  • 3步搞定Obsidian图片本地化:Local Images Plus插件终极指南
  • QuickRecorder:让macOS屏幕录制变得简单又高效 [特殊字符]
  • Umi-OCR:免费开源的文字识别解决方案,让图片中的文字“开口说话“
  • ResNet18镜像实战:智能相册自动打标、教育辅助、游戏截图分析全解析
  • 别再只用Polyline了!用Cesium自定义材质打造酷炫的动态箭头/脉冲线效果
  • 2026长沙网络推广公司实测|本地精准引流不踩坑,真实选型指南 - 亿仁imc
  • [多控制器适配] 通过BetterJoy实现Switch手柄在PC游戏中的无缝集成 [创新协议转换技术]
  • 如何突破硬件性能瓶颈?拯救者系列硬件配置工具让你的设备潜能全面释放
  • 2026年台车式退火炉厂家推荐:井式退火炉/箱式退火炉/溜槽加热退火炉专业制造商精选 - 品牌推荐官
  • 内网开发必备:手把手教你为Mapbox GL离线地图配置本地字体(附字体文件下载)
  • 为什么越来越多的人转行网络安全?网络安全前景如何?
  • 深度解析古文AI模型:GuwenBERT如何让机器读懂古代文献的技术揭秘
  • Visio网络拓扑图绘制实战:从基础操作到高级定制
  • BetterJoy终极指南:3大难题快速解决Switch控制器PC连接问题
  • Spring Boot整合 MinIO 生产级方案:大文件上传性能提升10倍
  • Vim党必备!Verilog-mode-v2插件全功能详解(附实战案例)
  • 人脸眼部特征检测数据集(千张图片已划分、已标注)适用于YOLO系列深度学习分类检测任务
  • 如何用3步实现全平台智能投递?多平台整合求职工具技术解析
  • 太原本地搬家公司哪家专业?首推尖兵搬家,居民/企业搬家/拆、装、卸一站式全覆盖 - 宁夏壹山网络
  • OpenClaw技能扩展指南:给nanobot镜像添加Markdown转换器
  • Windows 11系统优化终极指南:Win11Debloat让你的电脑重获新生
  • BG3ModManager全攻略:从基础配置到故障解决的模组管理大师之路
  • 实战项目开发,用快马平台生成stm32f103c8t6多引脚协同控制的智能小车代码
  • 07 AgentSkills 在 RAG 与知识库检索中的高级应用
  • 6个隐藏技巧:Dify工作流效率提升实战指南