找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 172|回复: 0

ObjectArx块内元素显示排序

[复制链接]

主题

0

回帖

0

积分

管理员

积分
0
发表于 2024-2-23 15:56:44 | 显示全部楼层 |阅读模式
1、AcDbSortentsTable
1.1、类简介
AcDbSortentsTable是绘制订单信息的持久容器。它位于关键的ACAD采用SORTENTS下的关联AcDbBlockTableRecord的扩展字典中。

AcDbSortentsTable包含一组对象ID /句柄对。对象ID是要绘制的实体的对象ID, 并且句柄是块表记录中的实体的句柄(通常但不总是与关联的对象ID不同), 其表示绘制顺序中的位置。实体按递增句柄值的顺序附加到块表记录中; 换句话说, 句柄值越高, 它就越晚出现在块表记录中。当在块表记录中绘制实体时, 迭代器以附加顺序遍历块表记录。在每个实体处, 获取句柄值并用于查询sortents表。如果匹配, 则绘制与sortents表中的句柄值关联的对象ID。如果sortents表中没有匹配项,  

当修改实体的绘制顺序时, 可以修改sortents表中的许多条目。例如, 块表记录具有五个具有以下句柄的实体(通常表示为表示十六进制数字的字符串):4A, 4B, 4C, 4D, 4E。这些句柄按升序显示。当应用程序在默认方向上迭代块表记录中的实体时, 句柄值总是从一个实体增加到next实体。

要先在空间中绘制最后一个实体(或“后面”其他实体), 必须在sortents表中创建五个条目, 如下所示:

实体ID

绘制订单处理

4E

4A

4A

4B

4B

4C

4C

4D

4D

4E

条目的顺序(表示为上表中的一行)无关紧要; 绘制订单处理在执行绘制时最终通过绘制顺序句柄对条目进行排序。换句话说, 在DXF文件中, 表条目可能按以下顺序出现, 但结果绘制顺序是相同的:

实体ID

绘制订单处理

4C

4D

4B

4C

4E

4A

4D

4E

4A

4B

作为另一示例, 空间中的最后一个实体在空间中的倒数第二个实体“下”移动, 但其余实体以“自然”顺序绘制。在这种情况下, sortents表只需要两个条目, 如下所示:

实体ID

绘制订单处理

4E

4D

4D

4E

使用隐式绘制顺序“last”将新实体添加到块表记录中不需要sortents表中的新条目。

1.2、成员方法
Acad::ErrorStatus moveToBottom( const AcDbObjectIdArray& ar);

将输入对象ID数组中指定的所有实体放置在绘制顺序的开头。被移动的实体保留其相对绘制顺序。

返回eInvalidInput如果任何输入对象ID不在相关的块, 或eDuplicateKey如果任何对象ID输入数组中出现两次。

2、代码实现
如果你要调整块内的显示顺序,就是获得AcDbBlockTableRecord的扩展辞典里面的ACAD采用SORTENTS,执行完参数后记得CLOSE返回的对象。

打开块时要先以块参照AcDbBlockReference对象打开,然后用AcDbBlockReference::blockTableRecord()获取块表记录blockTableRecordId,用这个blockTableRecordId打开才是块表记录,直接用块blkid打开块,将返回eNullObjectId错误。

  1. 获取块排序表对象
  2. AcDbSortentsTable * getSortentsTable(AcDbBlockTableRecord * pRec)
  3. {
  4.     if (!pRec)
  5.         return NULL;
  6.     Acad::ErrorStatus es;
  7.     AcDbObjectId ext采用id = pRec->extensionDictionary();
  8.     if (AcDbObjectId::kNull == ext采用id)
  9.     {
  10.         pRec->upgradeOpen();
  11.         es = pRec->createExtensionDictionary();
  12.         if (es != eOk)
  13.             return NULL;
  14.         pRec->downgradeOpen();
  15.         ext采用id = pRec->extensionDictionary();
  16.         if (AcDbObjectId::kNull == ext采用id)
  17.         {
  18.             return NULL;
  19.         }
  20.         pRec->downgradeOpen();
  21.     }
  22.     AcDbDictionary *pExt;
  23.     es = acdbOpenObject(pExt, ext采用id, AcDb::kForRead);
  24.     if (Acad::eOk != es)
  25.         return NULL;
  26.     AcDbObject *pObj;
  27.     if (Acad::eOk != pExt->getAt(采用T("ACAD采用SORTENTS"), pObj, AcDb::kForWrite))
  28.     {
  29.         if (Acad::eOk != pExt->upgradeOpen())
  30.         {
  31.             pExt->close();
  32.             return NULL;
  33.         }
  34.         AcDbSortentsTable *pSt = new AcDbSortentsTable;
  35.         if (NULL == pSt)
  36.         {
  37.             pExt->close();
  38.             return NULL;
  39.         }
  40.         AcDbObjectId new采用id;
  41.         if (Acad::eOk != pExt->setAt(采用T("ACAD采用SORTENTS"), pSt, new采用id))
  42.         {
  43.             delete pSt;
  44.             pExt->close();
  45.             return NULL;
  46.         }
  47.         pSt->setBlockId(pRec->objectId());
  48.         pObj = pSt;
  49.     }
  50.     pExt->close();
  51.     if (!pObj->isKindOf(AcDbSortentsTable::desc()))
  52.     {
  53.         pObj->close();
  54.         return NULL;
  55.     }
  56.     return (AcDbSortentsTable*)pObj;
  57. }
复制代码

  1. 遍历块实体,后置实体集合
  2. void softBlockEntity(const AcDbObjectId& blkid)
  3. {
  4.     // 后置实体集合
  5.     AcDbObjectIdArray behindids;
  6.     AcDbBlockTableRecordIterator *iter;
  7.     AcDbBlockReference *pBlkRef;
  8.     AcDbBlockTableRecord *pRecord;
  9.     Acad::ErrorStatus es = acdbOpenObject(pBlkRef, blkid, AcDb::kForRead);
  10.     if (es != Acad::eOk)
  11.         return;
  12.     AcDbObjectId blockTableRecordId = pBlkRef->blockTableRecord();
  13.     pBlkRef->close();
  14.     es = acdbOpenObject(pRecord, blockTableRecordId, AcDb::kForWrite);
  15.     if (es != Acad::eOk || pRecord == NULL)
  16.         return;
  17.     // 遍历块内实体
  18.     pRecord->newIterator(iter);
  19.     for (iter->start(); !iter->done(); iter->step())
  20.     {
  21.         AcDbObjectId id;
  22.         es = iter->getEntityId(id);
  23.         if (es != Acad::eOk || !id.isValid())
  24.             continue;
  25.         // 过滤出需要后置的实体集合           
  26.         if (筛选条件)
  27.             behindids.append(id);
  28.     }
  29.     AcDbSortentsTable *pSortentsTable = getSortentsTable(pRecord);
  30.     // 排序表对象在使用完后记得close
  31.     if (pSortentsTable != NULL)
  32.     {
  33.         es = pSortentsTable->moveToBottom(behindids);
  34.         pSortentsTable->close();
  35.     }
  36.     delete iter;
  37.     pRecord->close();
  38. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-28 14:40 , Processed in 0.133087 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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