The following code demonstrates how to modify a block table record's origin and compensate by moving the insertion point of each of the associated block references.
Please add the function 'testFunc' as a command.
void ResetAllInstances(AcDbBlockTableRecord * pBlockTableRecord,
AcGeVector3d &translation)
{
// Note that this function does not
// implement any error checking.
// We are assuming that pBlockTableREcord
// was opened for write by the calling function
// Iterate through all block references
// of this block table record.
AcDbBlockReferenceIdIterator * pIterator;
pBlockTableRecord->newBlockReferenceIdIterator(pIterator);
for (pIterator->start();!pIterator->done();
pIterator->step())
{
AcDbBlockReference * pBlockRef;
pIterator->getBlockReference(pBlockRef,
AcDb::kForWrite,true);
// Transform the translation vector from
// block coordinates to world coordinates.
AcGeVector3d realTranslation =
(pBlockRef->blockTransform())*translation;
// Translate the block reference to
// counter the effect of the origin change.
pBlockRef->setPosition(
pBlockRef->position()+realTranslation);
pBlockRef->close();
} // Next block reference
delete pIterator;
}
// This is command 'SGP'
void testFunc()
{
// Note that error checking is minimal.
ads_name ename ;
ads_point pt ;
// Ask the user to select an object
if( acedEntSel (
L"\nSelect the Block Reference",
ename, pt) != RTNORM )
return ;
// Open it
AcDbObjectId objId;
acdbGetObjectId (objId, ename) ;
AcDbEntity * pEnt;
acdbOpenObject (pEnt, objId, AcDb::kForRead);
// Check its a block reference
AcDbBlockReference *pRef =
AcDbBlockReference::cast(pEnt);
if (pRef == NULL)
{
pEnt->close();
return;
}
// Get the block reference's
// associated block table record.
AcDbObjectId blockId =pRef->blockTableRecord ();
pRef->close();
AcDbBlockTableRecord *pBlockTableRecord;
acdbOpenObject (pBlockTableRecord,
blockId, AcDb::kForWrite);
// Store the BTR's current
// origin (we'll need it later).
AcGePoint3d origin = pBlockTableRecord->origin();
// And set its new origin to (0, 0, 0)
pBlockTableRecord->setOrigin(AcGePoint3d(0, 0, 0));
// Create a translation vector for the change
// in displacement required to offset the
// origin change (in the block's coordinate system)
AcGeVector3d translation;
translation.set(-origin[X], -origin[Y], -origin[Z]);
// Now process all instances of this block
// reference to compensate for the change in the block origin
ResetAllInstances(pBlockTableRecord, translation);
pBlockTableRecord->close();
}
