CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

创建具有属性的块参照

2023-1-1 04:13| 发布者: admin| 查看: 432| 评论: 0|来自: AutoCAD

块引用是引用块表记录的实体。它包含一个插入点,ECS信息,X,Y,Z比例因子,旋转和法线向量(用于在新位置查看块的参数)。将块插入图形时,AutoCAD 通过创建块参照而不是将块本身复制到图形中来节省内存。

如果插入具有属性定义的块,则用户可以在运行时填写属性值,也可以在插入块时由应用程序填充属性值。

将具有属性的块插入到图形中

  1. 创建块参照图元 ()。AcDbBlockReference
  2. 调用该函数以指定引用的块表记录的对象 ID。(对象 ID 也可以直接在块引用的构造函数中指定。setBlockTableRecord()
  3. 将块参照追加到块表记录(模型空间、图纸空间或其他一些块)。
  4. 对引用的块表记录使用块表记录迭代器,搜索属性定义。对于找到的每个实体,创建一个新实体,用属性定义的数据填充它,然后使用 thefunction 将其附加到块引用中。AcDbAttributeappendAttribute()

下面的示例创建一个块参照,填充属性,然后将该参照追加到数据库。它使用全局函数来获取用户输入。上一节中显示的函数用于创建块参照。此示例使用块表记录迭代器逐步执行属性定义,并为每个属性定义创建相应的属性。属性值是使用 thefunction 从原始属性定义设置的。defineBlockWithAttributes()setPropertiesFrom()

void
addBlockWithAttributes()
{
    // Get an insertion point for the block reference,
    // definition, and attribute definition.
    //
    AcGePoint3d basePoint;
    if (acedGetPoint(NULL, "\nEnter insertion point: ",
        asDblArray(basePoint)) != RTNORM)
        return;
    // Get the rotation angle for the attribute definition.
    //
    double textAngle;
    if (acedGetAngle(asDblArray(basePoint),
        "\nEnter rotation angle: ", &textAngle) != RTNORM)
        return;
    // Define the height used for the attribute definition text.
    //
    double textHeight;
    if (acedGetDist(asDblArray(basePoint),
        "\nEnter text height: ", &textHeight) != RTNORM)
        return;
    // Build the block definition to be inserted.
    //
    AcDbObjectId blockId;
    defineBlockWithAttributes(blockId, basePoint,
        textHeight, textAngle);
    // Step 1: Allocate a block reference object.
    //
    AcDbBlockReference *pBlkRef = new AcDbBlockReference;
    // Step 2: Set up the block reference to the newly
    // created block definition.
    //
    pBlkRef->setBlockTableRecord(blockId);
    // Give it the current UCS normal.
    //
    struct resbuf to, from;
    from.restype = RTSHORT;
    from.resval.rint = 1; // UCS
    to.restype = RTSHORT;
    to.resval.rint = 0; // WCS
    AcGeVector3d normal(0.0, 0.0, 1.0);
    acedTrans(&(normal.x), &from, &to, Adesk::kTrue,
        &(normal.x));
    // Set the insertion point for the block reference.
    //
    pBlkRef->setPosition(basePoint);
    // Indicate the LCS 0.0 angle, not necessarily the UCS 0.0 angle.
    //
    pBlkRef->setRotation(0.0);
    pBlkRef->setNormal(normal);
    // Step 3: Open the current database's model space
    // block table record.
    //
    AcDbBlockTable *pBlockTable;
    acdbHostApplicationServices()->workingDatabase()
        ->getSymbolTable(pBlockTable, AcDb::kForRead);
    AcDbBlockTableRecord *pBlockTableRecord;
    pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
        AcDb::kForWrite);
    pBlockTable->close();
    // Append the block reference to the model space
    // block table record.
    //
    AcDbObjectId newEntId;
    pBlockTableRecord->appendAcDbEntity(newEntId, pBlkRef);
    pBlockTableRecord->close();
    // Step 4: Open the block definition for read.
    //
    AcDbBlockTableRecord *pBlockDef;
    acdbOpenObject(pBlockDef, blockId, AcDb::kForRead);
    // Set up a block table record iterator to iterate
    // over the attribute definitions.
    //
    AcDbBlockTableRecordIterator *pIterator;
    pBlockDef->newIterator(pIterator);
    AcDbEntity *pEnt;
    AcDbAttributeDefinition *pAttdef;
    for (pIterator->start(); !pIterator->done();
        pIterator->step())
    {
        // Get the next entity.
        //
        pIterator->getEntity(pEnt, AcDb::kForRead);
        // Make sure the entity is an attribute definition
        // and not a constant.
        //
        pAttdef = AcDbAttributeDefinition::cast(pEnt);
        if (pAttdef != NULL && !pAttdef->isConstant()) {
            // We have a non-constant attribute definition,
            // so build an attribute entity.
            //
            AcDbAttribute *pAtt = new AcDbAttribute();
            pAtt->setPropertiesFrom(pAttdef);
            pAtt->setInvisible(pAttdef->isInvisible());
            // Translate the attribute by block reference.
            // To be really correct, the entire block
            // reference transform should be applied here.
            //
            basePoint = pAttdef->position();
            basePoint += pBlkRef->position().asVector();
            pAtt->setPosition(basePoint);
            pAtt->setHeight(pAttdef->height());
            pAtt->setRotation(pAttdef->rotation());
            pAtt->setTag("Tag");
            pAtt->setFieldLength(25);
            char *pStr = pAttdef->tag();
            pAtt->setTag(pStr);
            free(pStr);
            pAtt->setFieldLength(pAttdef->fieldLength());
            // The database column value should be displayed.
            // INSERT prompts for this.
            //
            pAtt->setTextString("Assigned Attribute Value");
            AcDbObjectId attId;
            pBlkRef->appendAttribute(attId, pAtt);
            pAtt->close();
        }
        pEnt->close(); // use pEnt... pAttdef might be NULL
    }
    delete pIterator;
    pBlockDef->close();
    pBlkRef->close();
}

路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 15:29

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部