明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 308|回复: 1

Objectarx 对XDATA 进行封装

  [复制链接]
发表于 2025-6-28 10:29:42 | 显示全部楼层 |阅读模式
  1. #pragma once
  2. #include <acdb.h>
  3. #include <acedads.h>
  4. #include <AcString.h>
  5. #include <acutads.h>
  6. #include <adsdef.h>
  7. #include <cstdint>
  8. #include <dbhandle.h>
  9. #include <dbObject.h>
  10. #include <gepnt2d.h>
  11. #include <gepnt3d.h>
  12. #include <gevec2d.h>
  13. #include <gevec3d.h>

  14. class Xdata {
  15. public:

  16.   ~Xdata() {
  17.     clear();
  18.   }

  19.   Xdata(const AcString& appName) : appName(appName) {
  20.     acdbRegApp(appName); // 注册应用名
  21.     pRb = createRegAppNode(appName);
  22.     pTail = pRb;
  23.   }


  24.   void write(AcDbObject* pObj) {
  25.     if (pRb == nullptr || pRb->restype != Code::RegAppCode) {
  26.       auto head = createRegAppNode(appName);
  27.       head->rbnext = pRb;
  28.       pRb = head;
  29.     }
  30.     pObj->setXData(pRb);
  31.   }

  32.   void read(AcDbObject* pObj) {
  33.     clear();
  34.     resbuf* xdata = pObj->xData(appName);
  35.     if (!xdata) {
  36.       this->pRb = nullptr;
  37.       return;
  38.     };
  39.     copyResbufChain(xdata, &pRb, &pTail);
  40.   }

  41.   void print() {
  42.     if (pRb == nullptr) {
  43.       acutPrintf(L"\nNo Xdata for AppName [%s].\n", appName);
  44.     }
  45.     resbuf* next = pRb;
  46.     //int flag = 0;
  47.     while (true) {
  48.       if (next == nullptr)
  49.         return;
  50.       printNode(next);
  51.       next = next->rbnext;
  52.     }
  53.   }

  54.   //------------------------------
  55.   // 数据添加方法
  56.   //------------------------------
  57.   void addLayerName(const AcString& name) {
  58.     ads_u_val val;
  59.     val.setString(name);
  60.     addNode(Code::LayerCode, val);
  61.   }

  62.   void addString(const AcString& str) {
  63.     ads_u_val val;
  64.     val.setString(str);
  65.     addNode(Code::WstrCode, val);
  66.   }

  67.   void addInt16(short num) {
  68.     ads_u_val val;
  69.     val.setShort(num);
  70.     addNode(Code::Int16Code, val);
  71.   }

  72.   void addInt32(int32_t num) {
  73.     ads_u_val val;
  74.     val.setInt32(num);
  75.     addNode(Code::Int32Code, val);
  76.   }

  77.   void addDouble(double num) {
  78.     ads_u_val val;
  79.     val.setDouble(num);
  80.     addNode(Code::DoubleCode, val);
  81.   }
  82.   void addDist(double dist) {
  83.     ads_u_val val;
  84.     val.setDouble(dist);
  85.     addNode(Code::DistCode, val);
  86.   }

  87.   void addScale(double scale) {
  88.     ads_u_val val;
  89.     val.setDouble(scale);
  90.     addNode(Code::ScaleCode, val);
  91.   }

  92.   void addArray(double arr[3]) {
  93.     ads_u_val val;
  94.     val.setArray(arr[0], arr[1], arr[2]);
  95.     addNode(Code::ArrayCode, val);
  96.   }

  97.   void addPoint2d(const AcGePoint2d& pt) {
  98.     ads_u_val val;
  99.     val.setArray(pt.x, pt.y, 0);
  100.     addNode(Code::PointCode, val);
  101.   }

  102.   void addPoint3d(const AcGePoint3d& pt) {
  103.     ads_u_val val;
  104.     val.setArray(pt.x, pt.y, pt.z);
  105.     addNode(Code::PointCode, val);
  106.   }

  107.   void addDisp2d(const AcGeVector2d& vec) {
  108.     ads_u_val val;
  109.     val.setArray(vec.x, vec.y, 0);
  110.     addNode(Code::DispCode, val);
  111.   }

  112.   void addDisp3d(const AcGeVector3d& vec) {
  113.     ads_u_val val;
  114.     val.setArray(vec.x, vec.y, vec.z);
  115.     addNode(Code::DispCode, val);
  116.   }

  117.   void addDirect2d(const AcGeVector2d& vec) {
  118.     ads_u_val val;
  119.     val.setArray(vec.x, vec.y, 0);
  120.     addNode(Code::DirCode, val);
  121.   }
  122.   void addDirect3d(const AcGeVector3d& vec) {
  123.     ads_u_val val;
  124.     val.setArray(vec.x, vec.y, vec.z);
  125.     addNode(Code::DirCode, val);
  126.   }

  127.   void addHandle(const AcDbHandle& handle) {
  128.     ads_u_val val;
  129.     val.mn64data = handle.get64BitVal(); // 核心改动:使用原始字节写入
  130.     addNode(Code::HandleCode, val);
  131.   }
  132.   void clear() {
  133.     resbuf* curr = pRb;
  134.     while (curr) {
  135.       resbuf* next = curr->rbnext;
  136.       switch (curr->restype) {  // 去掉了rbinary处理
  137.       case Code::RegAppCode:
  138.       case Code::WstrCode:
  139.       case Code::LayerCode:
  140.         curr->releaseString();
  141.         break;
  142.       }
  143.       delete curr;
  144.       curr = next;
  145.     }
  146.     pRb = pTail = nullptr;
  147.   }
  148.   resbuf* createRegAppNode(const AcString& name) {
  149.     resbuf* node = new resbuf();
  150.     node->restype = AcDb::kDxfRegAppName;
  151.     node->setValue(name);
  152.     node->rbnext = nullptr;
  153.     return node;
  154.   }
  155. protected:
  156.   //------------------------------
  157.   // 内存管理核心方法
  158.   //------------------------------
  159.   resbuf* pRb = nullptr;
  160.   resbuf* pTail = nullptr;
  161.   AcString appName;

  162.   void copyResbufChain(const resbuf* src, resbuf** dstHead, resbuf** dstTail) {
  163.     resbuf* prev = nullptr;
  164.     for (const resbuf* curr = src; curr; curr = curr->rbnext) {
  165.       resbuf* node = new resbuf();
  166.       node->restype = curr->restype;

  167.       switch (curr->restype) { // 移除了rbinary处理
  168.       case Code::RegAppCode:
  169.       case Code::LayerCode:
  170.       case Code::WstrCode:
  171.         node->setValue(curr->resval.rstring);
  172.         break;
  173.       default:
  174.         node->resval = curr->resval;
  175.       }
  176.       node->rbnext = nullptr;
  177.       if (prev) prev->rbnext = node;
  178.       else *dstHead = node;

  179.       prev = node;
  180.     }
  181.     *dstTail = prev;
  182.   }

  183.   //------------------------------
  184.   // 工具方法
  185.   //------------------------------


  186.   //添加节点
  187.   void addNode(short restype, const ads_u_val& val) {
  188.     resbuf* node = new resbuf();
  189.     node->restype = restype;

  190.     switch (restype) {
  191.     case Code::RegAppCode:
  192.     case Code::LayerCode:
  193.     case Code::WstrCode:
  194.       node->setValue(val.rstring);
  195.       break;
  196.     default:
  197.       node->resval = val;
  198.     }

  199.     if (pTail) {
  200.       pTail->rbnext = node;
  201.       pTail = node;
  202.     }
  203.     else {
  204.       pRb = pTail = node;
  205.     }
  206.   }

  207.   //打印坐标
  208.   void printPoint(const double* point) {
  209.     acutPrintf(L"(%.2f, %.2f, %.2f)\n", point[0], point[1], point[2]);
  210.   }

  211.   // 打印节点
  212.   void printNode(resbuf* pNode) {
  213.     if (pNode == nullptr) {
  214.       acutPrintf(L"空节点");
  215.       return;
  216.     }
  217.     switch (pNode->restype) {
  218.     case Code::RegAppCode:
  219.       acutPrintf(L"[AppName] %s\n", pNode->resval.rstring);
  220.       break;

  221.     case Code::LayerCode:
  222.       acutPrintf(L"[LayerName] %s\n", pNode->resval.rstring);
  223.       break;

  224.     case Code::WstrCode:
  225.       acutPrintf(L"[AcString] %s\n", pNode->resval.rstring);
  226.       break;

  227.     case Code::Int16Code:
  228.       acutPrintf(L"[int16] %d\n", pNode->resval.rint);
  229.       break;

  230.     case Code::Int32Code:
  231.       acutPrintf(L"[int32] %ld\n", pNode->resval.rlong);
  232.       break;

  233.     case Code::DoubleCode:
  234.       acutPrintf(L"[double] %.3f\n", pNode->resval.rreal);
  235.       break;

  236.     case Code::ArrayCode:
  237.     case Code::PointCode:
  238.     case Code::DispCode:
  239.     case Code::DirCode:
  240.       acutPrintf(L"[int16] %d\n:", pNode->restype);
  241.       printPoint(pNode->resval.rpoint);
  242.       break;
  243.     case Code::HandleCode:
  244.       // 直接输出64位无符号整型
  245.       acutPrintf(L"[句柄] %I64u\n", pNode->resval.mn64data); // 修改此处格式说明符
  246.       break;
  247.     case Code::DistCode:
  248.       acutPrintf(L"[距离] %.3f\n", pNode->resval.rreal);
  249.       break;
  250.     case Code::ScaleCode:
  251.       acutPrintf(L"[比例] %.3f\n", pNode->resval.rreal);
  252.       break;
  253.     default:
  254.       acutPrintf(L"[未知类型:%d] \n", pNode->restype);
  255.       break;
  256.     }
  257.   }


  258.   enum Code :short
  259.   {
  260.     RegAppCode = 1001,  // Xdata 的 application name(组码1001)
  261.     WstrCode = 1000,    // ASCII 字符串的最大长度为 255 个字节(组码 1000)
  262.     LayerCode = 1003,   // 图层名(组码 1003)
  263.     ArrayCode = 1010,   // 3 个实数(组码 1010)
  264.     PointCode = 1011,   // 三维世界空间位置(组码 1011)
  265.     DispCode = 1012,    // 三维世界空间位移(组码 1012)
  266.     DirCode = 1013,     // 三维世界空间方向(组码 1013)
  267.     DoubleCode = 1040,  // 实数(组码 1040)
  268.     DistCode = 1041,    // 距离(组码 1041)
  269.     ScaleCode = 1042,   // 比例因子(组码 1042)
  270.     Int16Code = 1070,   // 一个 16 位整数(组码 1070)
  271.     Int32Code = 1071,   // 一个 32 位有符号长整数(组码 1071)
  272.     HandleCode = 1005   //一个句柄(组码1005)
  273.   };

  274. };
复制代码


回复

使用道具 举报

发表于 2025-6-29 13:28:21 | 显示全部楼层
学习了,谢谢分享,这个门槛有点高,学一段时间,又丢了,学不会。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-7-27 04:12 , Processed in 0.150606 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表