ObjectARX开发笔记(二)——使用Xdata向AutoCAD图形追加自定义数据

article/2025/11/7 13:47:07

1.自定义数据

ObjectARX开发过程中,有时会使用自定义数据,主要包括:

  • 自定义对象——可以让用户按照自己希望的方式封装数据,并向AutoCAD中添加第三方实体类型,这些实体类型用于与AutoCAD自身实体一样的特性,ObjectARX程序能够灵活控制自定义实体的显示。
  • 扩充数据——可以向图形本身或者图形中的实体追加一些数据。
    扩充数据又分为Xdata(eXtension data)和 Xrecord(eXtension record)两种。

2.Xdata

  • AutoCAD数据库的任何对象都可以灵活的附加一定数量的扩展数(Xdata),供开发者使用。
  • 扩展数据的含义由开发者自行解释,AutoCAD只维护这些数据而不管其具体的含义。
  • 扩展数据是链表组,每个组是链表系列,以一个名字开头以做标识。这个名字是应用程序名。
  • 应用程序名通过acdbRegApp()进行注册,最长可达31个字符 所附着的数据链表不能超过16K。
  • DXF组码只能采用1000~1071之间的组码值。

2.1 Xdata相关函数—acdbRegApp

定义

int acdbRegApp(const ACHAR * appname
);

作用:在当前图形中注册一个应用程序名称,用于分组,存储,检索和修改实体的扩展数据。appname必须遵守符号表名称(例如图层名称)的规则,且不能和已经存在的RegApp重复。每个新名称将产生一个新的acdbRegApp记录。
返回值

  • appname注册成功,返回RTNORM;
  • appname已存在,返回RTERROR;
  • appname注册失败,返回一个表明失败原因的系统变量ERRNO。

2.2 Xdata相关函数—setXData

定义

virtual Acad::ErrorStatus setXData(const resbuf* xdata
);

作用:设置一个对象的扩展数据。

  • 每个注册(regappname)链表以 restype = 1001 分界,并且resval.rstring应该是合法字符。
  • RegappName必须是AcDbRegAppTable中存在的。
  • 如果xdata中已经有该regappname组, 则新的链表将覆盖之 。
  • 要清除xdata中某个regappname的所有内容,只需建立一个以此regappname开头的空链表即可。

返回值

  • 如果xdata成功添加到对象,则返回Acad :: eOk。
  • 如果对象的xdata区域中没有足够的空间,则返回Acad::eXdataSizeExceeded。
  • 如果xdata中的所有regappName均不存在,则返回Acad :: eRegappIdNotFound。

2.3 Xdata相关函数—XData

定义

virtual resbuf* xData(const ACHAR* regappName = nullptr
) const;

作用:获取一个对象中名为“regappName”的扩展数据。如果regappName == NULL,则返回所有xdata,否则仅返回指定名称为regappName的xdata。如果需要多个regappName的xdata,则必须对该成员函数进行多次调用,每个regappName调用一次。
返回值

  • 返回包含对象xdata副本的resbuf结构的链接列表。

2.4 Xdata实例,添加、查看和删除Xdata

添加Xdata代码如下:

//添加Xdatastatic void MyGroupaddXdata() {//提示用户选择对象AcDbObject* pObj = selectObject(AcDb::kForRead);if (!pObj) {acutPrintf(_T("Error selecting object\n"));return;}//获取Xdata名称TCHAR appName[132], resString[200];appName[0] = resString[0] = _T('\0');acedGetString(NULL, _T("Enter application name: "), appName);acedGetString(NULL, _T("Enter string to be added: "), resString);struct  resbuf  *pRb, *pTemp;pRb = pObj->xData(appName);if (pRb != NULL) {//如果Xdata已经存在,不执行任何操作for (pTemp = pRb; pTemp->rbnext != NULL;pTemp = pTemp->rbnext){ ; }} else {//如果Xdata不存在,向当前对象注册名为appName的XdataacdbRegApp(appName);pRb = acutNewRb(AcDb::kDxfRegAppName);pTemp = pRb;pTemp->resval.rstring= (TCHAR*) malloc((_tcslen(appName) + 1) * sizeof(TCHAR));_tcscpy(pTemp->resval.rstring, appName);}//向新注册的Xdata添加自定义扩展数据pTemp->rbnext = acutNewRb(AcDb::kDxfXdAsciiString);pTemp = pTemp->rbnext;pTemp->resval.rstring= (TCHAR*) malloc((_tcslen(resString) + 1) * sizeof(TCHAR));_tcscpy(pTemp->resval.rstring, resString);//把对象从AcDb::kForRead 状态变成AcDb::kForWrite状态pObj->upgradeOpen();pObj->setXData(pRb);pObj->close();acutRelRb(pRb);}

查看Xdata代码如下:

//显示Xdata
static void MyGroupprintXdata(){//提示用户选择对象AcDbObject *pObj;if ((pObj = selectObject(AcDb::kForRead)) == NULL) {return;}//获取Xdata名称TCHAR appname[133];if (acedGetString(NULL,_T("\nEnter the desired Xdata application name: "),appname) != RTNORM){return;}// 根据Xdata名称appname,调用printList()函数输出Xdata信息struct resbuf *pRb;pRb = pObj->xData(appname);if (pRb != NULL) {printList(pRb);acutRelRb(pRb);} else {acutPrintf(_T("\nNo xdata for this appname"));}pObj->close();}

删除Xdata代码如下:

//删除Xdatastatic void MyGroupdeleteXdata(){AcDbObject* pObj = selectObject(AcDb::kForRead);if (!pObj) {acutPrintf(_T("Error selecting object\n"));return;}//获取Xdata名称		TCHAR appName[132];appName[0] = _T('\0');acedGetString(NULL, _T("Enter application name: "), appName);//在pObj的Xdata中查找appNamestruct resbuf *pTemp = nullptr; pTemp = pObj -> xData(appName);if (pTemp != nullptr){// 删除名为appName的XdataacdbRegApp(appName);struct resbuf* pRb = acutBuildList(AcDb::kDxfRegAppName, appName, RTNONE);pObj->upgradeOpen();pObj->setXData(pRb);acutRelRb(pRb);acutPrintf(TEXT("\nXdata deleted successfully."));}else{//未找到需要删除的XdataacutPrintf(TEXT("\nNo Xdata found."));}acutRelRb(pTemp);pObj->close();}

还需要添加两个函数,printList()用于在命令窗口中打印Xdata信息;selectObject()用于提示用户选择实体。代码如下:

//在AutoCAD命令窗口中打印Xdata信息static void printList(struct resbuf* pRb){int rt, i;TCHAR buf[133];for (i = 0;pRb != NULL;i++, pRb = pRb->rbnext) {if (pRb->restype < 1010) {rt = RTSTR;} else if (pRb->restype < 1040) {rt = RT3DPOINT;} else if (pRb->restype < 1060) {rt = RTREAL;} else if (pRb->restype < 1071) {rt = RTSHORT;} else if (pRb->restype == 1071) {rt = RTLONG;} else {rt = pRb->restype; }switch (rt) {case RTSHORT:if (pRb->restype == RTSHORT) {acutPrintf(_T("RTSHORT : %d\n"), pRb->resval.rint);} else {acutPrintf(_T("(%d . %d)\n"), pRb->restype,pRb->resval.rint);};break;case RTREAL:if (pRb->restype == RTREAL) {acutPrintf(_T("RTREAL : %0.3f\n"),pRb->resval.rreal);} else {acutPrintf(_T("(%d . %0.3f)\n"), pRb->restype,pRb->resval.rreal);};break;case RTSTR:if (pRb->restype == RTSTR) {acutPrintf(_T("RTSTR : %s\n"),pRb->resval.rstring);} else {acutPrintf(_T("(%d . \"%s\")\n"), pRb->restype,pRb->resval.rstring);};break;case RT3DPOINT:if (pRb->restype == RT3DPOINT) {acutPrintf(_T("RT3DPOINT : %0.3f, %0.3f, %0.3f\n"),pRb->resval.rpoint[X],pRb->resval.rpoint[Y],pRb->resval.rpoint[Z]);} else {acutPrintf(_T("(%d %0.3f %0.3f %0.3f)\n"),pRb->restype,pRb->resval.rpoint[X],pRb->resval.rpoint[Y],pRb->resval.rpoint[Z]);}break;case RTLONG:acutPrintf(_T("RTLONG : %dl\n"), pRb->resval.rlong);break;}if ((i == 23) && (pRb->rbnext != NULL)){i = 0;acedGetString(0,_T("Press <ENTER> to continue..."), buf);}}}//提示用户选择实体static AcDbObject*	selectObject(AcDb::OpenMode openMode){int ss;ads_name en;ads_point pt;acedInitGet(RSG_OTHER, _T("Handle _Handle"));ss = acedEntSel(_T("\nSelect an Entity or enter")_T(" 'H' to enter its handle:  "), en, pt);TCHAR handleStr[132];AcDbObjectId eId;switch (ss) {case RTNORM:   break;case RTKWORD:if ((acedGetString(Adesk::kFalse,_T("Enter Valid Object Handle: "),handleStr) == RTNORM)&& (acdbHandEnt(handleStr, en) == RTNORM)){break;}default:acutPrintf(_T("Nothing Selected, Return Code==%d\n"),ss);return NULL;}Acad::ErrorStatus retStat;retStat = acdbGetObjectId(eId, en);if (retStat != Acad::eOk) {acutPrintf(_T("\nacdbGetObjectId failed"));acutPrintf(_T("\nen==(%lx,%lx), retStat==%d\n"),en[0], en[1], eId);return NULL;}AcDbObject* obj;if ((retStat = acdbOpenObject(obj, eId, openMode))!= Acad::eOk){acutPrintf(_T("acdbOpenEntity failed: ename:(%lx,%lx),")_T(" mode:%d retStat:%d"), en[0], en[1],openMode, retStat);return NULL;}return obj;}

3.代码效果

使用“addXdata”命令选择实体并添加扩展数据,“printXdata”命令在AutoCAD的命令窗口显示添加的扩展数据,“deleteXdata”命令删除扩展数据。如下图所示,使用Xdata向图中被选中直线追加了自定义数据。
在这里插入图片描述

4.源代码

源代码:xData
提取码:4bbm

参考文档
[1]:Autodesk ObjectARX for AutoCAD 2015: Developer Guide.


http://chatgpt.dhexx.cn/article/BakyijXD.shtml

相关文章

matlab xdata ydata,matlab中set(head1,'xdata',x1,'ydata',y1)什么意思?

满意答案 amuese6418 2014.10.25 采纳率&#xff1a;59% 等级&#xff1a;12 已帮助&#xff1a;8722人 这个主要是set的用法 它是功能 设置对象的属性。 用法 set(H,PropertyName,PropertyValue,…) 用属性值PropertyValue设置关于用参量H 标志的对象(一个或多个)的属性名P…

用Proteus仿真C51时用到xdata时的问题

在用做一个程序&#xff0c;但是51的内存资源太过稀有&#xff0c;使用到较大的数组的时候资源很快就耗尽了&#xff0c;可能会遇到以下错误&#xff1a; src\main.c(195): error C249: DATA: SEGMENT TOO LARGE这时需要用到大模式下编译。 然而在proteus下默认xdata是必须加…

xdata,volatile,extern,static,#pragma 关键字

1. xdata xdata&#xff1a;声明的变量位于外部 RAM 地址范围内某一位置。 2. volatile volatile: 的本意是“易变的” &#xff0c;因为访问寄存器要比访问内存单元快的多&#xff0c;所以编译器一般都会作减少存取内存的优化。当要求使用 volatile 声明变量值的时候&#…

51 单片机 data idata xdata 使用

51 单片机 data idata xdata 使用 简介 该篇文章只提使用&#xff0c;先不详细讲解&#xff0c;使用的原因就是自己写的代码 ROM 超了&#xff01;&#xff01;&#xff01;新建工程默认使用 data Keil 配置如下图 测试芯片FlashRAMSTC15W408AS8Kbyte512byte data idata xd…

TMS XData 4.6.0.1 Full Source XE2-DX10.3

TMS XData 4.6.0.1 Full Source XE2-DX10.3 用于多层REST / JSON HTTP / HTTPS应用服务器开发和ORM远程处理的Delphi框架。 TMS XData功能概述 基于REST / JSON架构样式的服务器 由于它是基于REST / JSON的&#xff0c;因此可以轻松地从不同的客户端平台(如.NET&#xff0c;Jav…

10.扩展数据(XData)

愿你出走半生,归来仍是少年&#xff01; 环境&#xff1a;.NET FrameWork4.5、ObjectArx 2016 64bit、Entity Framework 6. CAD中所有数据库对象都包含一个可以供开发人员进行自定义的对象&#xff1a;XDATA,本文主要针对此对象进行探索。 XDATA的使用中需要使用到部分DXFCOD…

【51】单片机中的data、idata、xdata、code等关键字的作用

说明 data&#xff1a;RAM低128字节&#xff0c;响应速度最快&#xff0c;采用直接寻址方式 idata&#xff1a;RAM高128字节&#xff0c;采用间接寻址方式&#xff0c;速度相对较慢 bdata&#xff1a;片内RAM&#xff0c;位寻址方式 xdata&#xff1a;外部扩展RAM&#xff…

Kmeans算法

Kmeans算法 是最简单的聚类算法之一&#xff0c;算法接受参数 k &#xff1b;然后将事先输入的n个数据对象划分为k个聚类以便使得所获得的聚类满足&#xff1a;同一聚类中的对象相似度较高&#xff1b;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得…

图像分割与实战(一)——基于主动轮廓(snake)的图像分割

1.主动轮廓图像分割算法的概述 1.1主要思想 将图像分割问题转化为轮廓进化问题 1.2工作原理 将一条曲线在内外力的共同作用下&#xff0c;使得曲线逐步收敛到目标轮廓 1.3 算法流程 初始化曲线利用内外力更新曲线判断曲线是否收敛&#xff0c;否则返回第2步 1.4 需要解决…

实时实例分割算法Deep Snake,速度32.3fps|CVPR 2020

论文提出基于轮廓的实例分割方法Deep snake&#xff0c;轮廓调整是个很不错的方向&#xff0c;引入循环卷积&#xff0c;不仅提升了性能还减少了计算量&#xff0c;保持了实时性&#xff0c;但是Deep snake的大体结构不够优雅&#xff0c;应该还有一些工作可以补&#xff0c;推…

数字图像处理笔记——Snakes算法、活动轮廓以及水平集(Snakes, active contours, and level sets)

Snakes算法 上一讲我们讲的图像分割算法主要是基于像素的&#xff0c;这一讲主要是基于曲线的。我们希望能得到一个能够包围住图像轮廓的平滑的曲线&#xff0c;snakes算法就是一个很有用的算法。首先我们将曲线的坐标x、y同一用参数s表示&#xff0c;s范围从0-1代表从起点绕曲…

Deep Snake for Real-Time Instance Segmentation:基于Deep Snake的实例实时分割

本文针对自己所看的 Deep Snake 做一个总结和存档&#xff0c;也方便其他同学学习 —— 阿波&#xff0c;2020.4.23 论文原文&#xff1a;Deep Snake for Real-Time Instance Segmentation 代码地址&#xff1a; snake 本篇文章工作有以下贡献&#xff1a; •提出了一种基于…

KMeans算法流程

一、什么是簇&#xff1f; 我们知道聚类就是让机器把数据集中的样本按照特征的性质分组&#xff0c;直观上来看&#xff0c;簇是一组一组聚集在一起的数据&#xff0c;在 一个簇 中的数据就认为是 同一类 &#xff0c;簇就是聚类的结果表现。实际上簇并没有明确的定义&#xf…

HZNUCTF MISC Snake题解——python程序逆向,hashcat爆破sha256

目录 一.Dump得到pyc文件 二.pyc反编译得到py源码 三.分析程序逻辑 四.hashcat爆破 题目附件链接&#xff1a;https://pan.baidu.com/s/1CcS8BPGx8fKnsJgRvEi0bA?pwdt2yj 提取码&#xff1a;t2yj 一.Dump得到pyc文件 使用命令:python pyinstxtractor.py snake.exe 二.p…

DeepSnake实现实例分割

文章目录 简介&#xff1a;环境配置Demo实现全文总结参考文献 简介&#xff1a; DeepSnake(Deep Snake for Real-Time Instance Segmentation)作为CVPR 2020 oral论文&#xff0c;在实例分割任务上取得了实时分割效果的同时&#xff0c;还保持着非常不错的性能&#xff0c;该论…

【主动轮廓模型(二)】《GVF Snake》算法原理与OpenCV实现

文章目录 1 问题引入1.1 传统Snake模型的缺陷1.2 亥姆霍兹定理&#xff08;Helmholtz theorem&#xff09; 2 GVF Snake2.1 边缘图&#xff08;Edge Map&#xff09;2.2 梯度矢量流&#xff08;Gradient Vector Flow&#xff0c;GVF&#xff09;2.3 数值求解方法 3 OpenCV实现 …

用于实时实例分割的Deep Snake算法

第一部分&#xff1a;创新及其优点 第二部分&#xff1a;算法原理 第三部分&#xff1a;实验过程 第四部分&#xff1a;程序逻辑 1 创新及其优点 Deep Snake算法建立在传统Snake算法的基础上&#xff0c;将snake算法做成了轮廓结构化特征学习的方法&#xff0c;使用了循环卷积…

KMeans 算法(一)

K-means算法简述 K-means算法&#xff0c;也称为K-平均或者K-均值&#xff0c;一般作为掌握聚类算法的第一个算法。这里的K为常数&#xff0c;需事先设定&#xff0c;通俗地说该算法是将没有标注的 M 个样本通过迭代的方式聚集成K个簇。在对样本进行聚集的过程往往是以样本之间…

选择性搜索算法(Selective Search )——SS算法

文章目录 一、前言二、object Detection VS object Recognition&#xff08;Selective Search的提出&#xff09;2.1object recognition与object detection的关系2.2滑动窗口方法的局限性2.3Selective search算法的提出 三、Selective Search算法3.1什么是Selective Search&…

主动轮廓模型——Snake分割算法(MATLAB)

学习图像分割算法&#xff0c;在网上找到的关于主动轮廓模型的实现代码&#xff0c;自己简化总结了一下&#xff0c;在这里和大家分享&#xff0c;欢迎提问 snake是一种能量最小的曲线&#xff0c;表示为v(s) (x(s), y(s)), s为归一化的曲线长度&#xff0c;s∈[0, 1]。 能量…