Issue
I want to be able to work with a drawing which contains custom entities, for which I do not have the relevant application. I would like to be able to use the data in the drawing, for example for constructing new geometry. Some entities I can explode, but others I cannot, as they are marked as being not-erasable, I get the AutoCAD entity(ies) equivalent but the custom entity is still there. What can I do?
Solution
It is possible to use ObjectARX to change all proxy entities for something else. The sample code does the following: Iterate through the entire drawing, and swaps all proxy entities for anonymous blocks. The blocks contain the equivalent geometry of the proxy entities. Note that this will not allow the creating entity to recover the information stored in the original entities.
AcDbObjectIdArray proxies;
// Iterate through the records
// Make a list of all the proxies, and then process them afterwards.
AcDbBlockTable* pTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(
pTable,
AcDb::kForRead
);
if (pTable == NULL)
{
return;
}
AcDbBlockTableIterator* pTableIter;
for (pTable->newIterator(pTableIter); !pTableIter->done(); pTableIter->step())
{
AcDbBlockTableRecord* pRecord;
pTableIter->getRecord(pRecord, AcDb::kForRead);
if (pRecord == NULL)
{
acutPrintf(_T("\nCannot open a BTR"));
continue;
}
AcDbBlockTableRecordIterator* pRecordIter;
for (pRecord->newIterator(pRecordIter);
!pRecordIter->done();
pRecordIter->step())
{
AcDbEntity* pEnt;
pRecordIter->getEntity(pEnt, AcDb::kForRead);
if (pEnt != NULL)
{
if (pEnt->isKindOf(AcDbProxyEntity::desc()))
{
proxies.append(pEnt->objectId());
}
pEnt->close();
}
}
delete pRecordIter;
pRecord->close();
}
delete pTableIter;
if (Acad::eOk != pTable->upgradeOpen())
{
acutPrintf(_T("\nCannot open table for Write"));
pTable->close();
return;
}
int nProxies = proxies.length();
for (int i = 0; i < nProxies; i++)
{
AcDbProxyEntity* pProxy;
AcDbObject* pObj;
acdbOpenAcDbObject(pObj, proxies[i], AcDb::kForRead);
pProxy = AcDbProxyEntity::cast(pObj);
if (NULL == pProxy)
{
pObj->close();
continue;
}
AcDbVoidPtrArray explodedEnts;
pProxy->explode(explodedEnts);
int nExplodedEnts = explodedEnts.length();
if (nExplodedEnts > 0)
{
AcDbBlockTableRecord* pRecord = new AcDbBlockTableRecord();
pRecord->setName(_T("*B"));
AcDbObjectId blockId;
pTable->add(blockId, pRecord);
for (int j = 0; j < nExplodedEnts; j++)
{
AcDbEntity* pEnt = (AcDbEntity*)(explodedEnts[j]);
pRecord->appendAcDbEntity(pEnt);
pEnt->setColorIndex(0);
pEnt->close();
}
pRecord->close();
AcDbBlockTableRecord* pOwningRecord;
acdbOpenObject(
pOwningRecord,
pProxy->ownerId(),
AcDb::kForWrite
);
if (NULL != pOwningRecord)
{
AcDbBlockReference* pRef = new AcDbBlockReference;
pRef->setBlockTableRecord(blockId);
pOwningRecord->close();
pProxy->upgradeOpen();
pProxy->handOverTo(pRef);
pRef->setColor(pProxy->color());
pRef->setLayer(pProxy->layerId());
pRef->setVisibility(pProxy->visibility());
delete pProxy;
pRef->close();
}
}
else
{
pProxy->close();
}
}
pTable->close();

Leave a Reply