admin 发表于 2024-2-28 08:53:26

Arx遍历块内实体

1、关键类和接口

1.1、AcDbBlockTableRecordIterator

该迭代器由函数AcDbBlockTableRecord::newIterator()返回。它用于迭代AcDbBlockTableRecord。使用之后要释放(delete)返回的对象。

void start( bool atBeginning = true, bool skipDeleted = true);

此函数用于将迭代器的位置初始化为块的开头或结尾。如果atBeginning为true, 则迭代器位于表的开头; 否则, 它位于表的末尾。如果skipDeleted为true, 则迭代器位于第一个或最后一个非删除实体; 否则, 它位于第一个或最后一个实体, 无论其被删除或未删除状态。

bool done() const;

如果迭代器已经定位在块的任一端之外, 则此函数返回true ; 否则, 它返回false。

void step( bool forward = true, bool skipDeleted = true);

此函数将迭代器移动到块中的下一个(或上一个)实体。如果forward为true, 则迭代器逐步向块的末尾移动; 否则, 它会走向块的开头。如果skipDeleted为true, 则将跳过已擦除的块; 否则, 任何已擦除的块都将包含在扫描中。

Acad::ErrorStatus getEntityId( AcDbObjectId& entityId) const;

该函数返回AcDbObjectId在该迭代器被定位在该实体的ENTITYID。

1.2、AcDbBlockReference

该AcDbBlockReference类表示在AutoCAD的INSERT实体。块引用用于放置, 调整和显示它引用的AcDbBlockTableRecord中的实体集合的实例。此外, 块引用可以是AcDbAttribute实体的所有者(其列表由AcDbSequenceEnd实体自动终止)。

从AcDbEntity继承的AcDbBlockReference集函数忽略doSubents参数, 因为这些子实体是真正特殊文本实体的属性, 需要具有各自的属性(与折线顶点不同, 它们只是数据点)。

AcDbObjectId blockTableRecord() const;

此函数返回块引用引用的AcDbBlockTableRecord的对象ID 。

引用的块表记录包含块引用将显示的实体。

块表记录对象ID用于获取与块引用的AutoLISP和ADSRX实体信息列表中的组代码-2一起使用的实体名称。

1.3、AcDbBlockTableRecord

AcDbBlockTableRecord类的对象用作图形文件数据库中实体的容器。AcDbBlocktableRecord对象(通常称为BTR)由数据库的AcDbBlockTable对象拥有。BTR又拥有它们包含的实体对象。

每个数据库中始终存在两个特殊的BTR。它们是* MODEL采用SPACE和* PAPER采用SPACE。它们是数据库的模型和纸空间。AutoCAD中在模型空间中创建的任何实体都由* MODEL采用SPACE BTR拥有和包含。在Paper Space中创建的实体进入* PAPER采用SPACE BTR。

除了* MODEL采用SPACE和* PAPER采用SPACE之外的BTR在以前版本的AutoCAD中已知为块定义, 并且由AcDbBlockReferences(通常称为插入)引用。BTR包含一组实体, 可以通过多个插入引用以节省图形中的空间, 节省绘图创建时间, 并保证所有插入显示相同(可能除了颜色和线型)。

2、代码实例

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

void readBlockEntities(const AcDbObjectId& blkid)
{
    AcDbBlockTableRecordIterator *iter;
    AcDbBlockReference *pBlkRef;
    AcDbBlockTableRecord *pRecord;
    Acad::ErrorStatus es = acdbOpenObject(pBlkRef, blkid, AcDb::kForRead);
    if (es != Acad::eOk)
      return;
    AcDbObjectId blockTableRecordId = pBlkRef->blockTableRecord();
    pBlkRef->close();
    es = acdbOpenObject(pRecord, blockTableRecordId, AcDb::kForWrite);
    if (es != Acad::eOk || pRecord == NULL)
      return;
    pRecord->newIterator(iter);
    for (iter->start(); !iter->done(); iter->step())
    {
      AcDbObjectId id;
      es = iter->getEntityId(id);
      if (es != Acad::eOk || !id.isValid())
            continue;
      // TODO 处理实体
    }
    // 释放迭代器对象,关闭快表记录
    delete iter;
    pRecord->close();
}
页: [1]
查看完整版本: Arx遍历块内实体