Creating a Block Table Record with Attribute Definitions

An AutoCAD block is a collection of entities that is stored in a block table record. Each block has an AcDbBlockBegin object, followed by one or more AcDbEntity objects, and ends with an AcDbBlockEnd object (see the illustration under Entity Ownership).

A block can contain attribute definitions, which are templates for creating attributes. An attribute is informational text associated with a block. Depending on a user-supplied setting, attribute values may or may not be copied when a block is inserted into a drawing. Often, the application prompts the user for the attribute value at runtime.

To create a block table record

  1. Create a new block table record.
  2. Add the block table record to the block table.
  3. Create entities and add them to the block table record.
  4. Create attribute definitions, set their values, and add them to the block table record.

When you close the block table record, the block begin and block end objects are added to the block automatically.

The following example creates a new block table record named

ASDK-BLOCK-WITH-ATTR and adds it to the block table. Next it creates a circle entity and adds it to the new block table record. It creates two attribute definition entities (the second is a clone of the first) and appends them to the same block table record

void
defineBlockWithAttributes(
    AcDbObjectId& blockId, // This is a returned value.
    const AcGePoint3d& basePoint,
    double textHeight,
    double textAngle)
{
    int retCode = 0;
    AcDbBlockTable *pBlockTable = NULL;
    AcDbBlockTableRecord* pBlockRecord = new AcDbBlockTableRecord;
    AcDbObjectId entityId;
    // Step 1: Set the block name and base point of the 
    // block definition.
    //
    pBlockRecord->setName("ASDK-BLOCK-WITH-ATTR");
    pBlockRecord->setOrigin(basePoint);
    // Open the block table for write.
    //
    acdbHostApplicationServices()->workingDatabase()
        ->getSymbolTable(pBlockTable, AcDb::kForWrite);
    // Step 2: Add the block table record to block table.
    //
    pBlockTable->add(blockId, pBlockRecord);
    // Step 3: Create a circle entity.
    //
    AcDbCircle *pCircle = new AcDbCircle;
    pCircle->setCenter(basePoint);
    pCircle->setRadius(textHeight * 4.0);
    pCircle->setColorIndex(3);
    // Append the circle entity to the block record.
    //
    pBlockRecord->appendAcDbEntity(entityId, pCircle);
    pCircle->close();
    // Step 4: Create an attribute definition entity.
    //
    AcDbAttributeDefinition *pAttdef
        = new AcDbAttributeDefinition;
    // Set the attribute definition values.
    //
    pAttdef->setPosition(basePoint);
    pAttdef->setHeight(textHeight);
    pAttdef->setRotation(textAngle);
    // For horizontal modes other than AcDb::kTextLeft
    // and vertical modes other than AcDb::kTextBase,
    // you may need to call setAlignmentPoint(). See the
    // AcDbText::setAlignmentPoint() documentation for details.
    pAttdef->setHorizontalMode(AcDb::kTextLeft);
    pAttdef->setVerticalMode(AcDb::kTextBase);
    pAttdef->setPrompt("Prompt");
    pAttdef->setTextString("DEFAULT");
    pAttdef->setTag("Tag");
    pAttdef->setInvisible(Adesk::kFalse);
    pAttdef->setVerifiable(Adesk::kFalse);
    pAttdef->setPreset(Adesk::kFalse);
    pAttdef->setConstant(Adesk::kFalse);
    pAttdef->setFieldLength(25);
    // Append the attribute definition to the block.
    //
    pBlockRecord->appendAcDbEntity(entityId, pAttdef);
    // The second attribute definition is a little easier
    // because we are cloning the first one.
    //
    AcDbAttributeDefinition *pAttdef2
        = AcDbAttributeDefinition::cast(pAttdef->clone());
    // Set the values that are specific to the
    // second attribute definition.
    //
    AcGePoint3d tempPt(basePoint);
    tempPt.y -= pAttdef2->height();
    pAttdef2->setPosition(tempPt);
    pAttdef2->setColorIndex(1); // Red
    pAttdef2->setConstant(Adesk::kTrue);
    // Append the second attribute definition to the block.
    //
    pBlockRecord->appendAcDbEntity(entityId, pAttdef2);
    pAttdef->close();
    pAttdef2->close();
    pBlockRecord->close();
    pBlockTable->close();
    return;
}