The first thing you need to know is: in AutoCAD, block definitions are AcDbBlockTableRecords, just as are “MODEL_SPACE” and “PAPER_SPACE” records. A Block definition typically has entities and AcDbAttributeDefinition objects associated with it. To add a new attribute to the block definition, it is a matter of adding another AcDbAttributeDefinition to the AcDbBlockTableRecord in which you are interested.
Adding a New Attribute Definition
The following code adds one AcDbAttributeDefinition to a block definition. It assumes a drawing is open and there is a block named “Test” in the drawing.
void AddNewAtt()
{
AcDbDatabase *pCurDb;
AcDbBlockTable* pBlkTbl;
AcDbBlockTableRecord* pBlkRec;
AcDbObjectId attId;
Acad::ErrorStatus es;
AcDbAttributeDefinition* pAttDef;
// Location of the AttributeDefinition in the block definition
AcGePoint3d attLoc(1.2, -0.5, 0);
// Specify the text, tag and prompt
ACHAR text[] = {L"NEW VALUE ADDED"};
ACHAR tag[] = {L"MYTAG"};
ACHAR prompt[] = {L"Enter a new value"};
pCurDb = acdbHostApplicationServices()->workingDatabase();
es = pCurDb->getBlockTable(pBlkTbl, AcDb::kForRead);
if(!pBlkTbl->has(L"TEST"))
{
acutPrintf(L"\nBlock definition TEST does not exist");
pBlkTbl->close();
return;
}
es = pBlkTbl->getAt(L"TEST", pBlkRec, AcDb::kForWrite);
// Create an AttributeDefinition
pAttDef = new AcDbAttributeDefinition(attLoc, text, tag, prompt);
// Append the AttributeDefinition to the block definition
es = pBlkRec->appendAcDbEntity(attId, pAttDef);
pAttDef->close();
pBlkRec->close();
pBlkTbl->close();
}
Updating Existing Block References
Now the block definition is modified. If you insert a new block reference, you will be prompted for the attribute value. However, existing block references do not have these values yet. To set them, you must iterate through all block references and update them.
void UpdateATT()
{
AcDbDatabase *pCurDb = acdbHostApplicationServices()->workingDatabase();
AcDbBlockTable* pBlkTbl;
Acad::ErrorStatus es = pCurDb->getBlockTable(pBlkTbl, AcDb::kForRead);
if(!pBlkTbl->has(L"TEST"))
{
acutPrintf(L"\nBlock definition TEST does not exist");
pBlkTbl->close();
return;
}
AcDbBlockTableRecord *pBlkRec;
es = pBlkTbl->getAt(L"TEST", pBlkRec, AcDb::kForWrite);
if(es != Acad::eOk)
{
acutPrintf(L"\nError opening block definition.");
pBlkTbl->close();
return;
}
// Get the block references that use this definition
AcDbObjectIdArray ids;
pBlkRec->getBlockReferenceIds(ids);
pBlkRec->close();
pBlkTbl->close();
// Iterate through each block reference
for(int i=0; i < ids.length(); i++)
{
AcDbBlockReference *pBlkRef;
es = acdbOpenObject(pBlkRef, ids[i], AcDb::kForWrite);
if (es == Acad::eOk)
{
AcDbObjectIterator *pAttribIter = pBlkRef->attributeIterator();
for(pAttribIter->start(); !pAttribIter->done(); pAttribIter->step())
{
AcDbObjectId blkRefAttId = pAttribIter->objectId();
AcDbAttribute *pBlkRefAtt;
es = pBlkRef->openAttribute(pBlkRefAtt, blkRefAttId, AcDb::kForWrite);
if (es == Acad::eOk)
{
ACHAR *pAttTag = pBlkRefAtt->tag();
if(_tcscmp(pAttTag, L"MYTAG") == 0)
{
// Update the attribute value
pBlkRefAtt->setTextString(L"My Value");
}
acutDelString(pAttTag);
pBlkRefAtt->close();
}
}
delete pAttribIter;
pBlkRef->close();
}
}
}

Leave a Reply