|
cDbBlockReference::explode fails
问题:
Why does AcDbBlockReference::explode produce incorrect results if there are
AcDbText or AcDbAttribute definition entities in the block that is exploded?
解答:
This isa known problem that is desribed in DevNote #TS36113.
AcDbBlockReference::explode internally calls AcDbText::getTransformedCopy that
produces incorrect results. The code below uses the code in DevNote #TS36113 to
explode an AcDbBlockReference correctly.
普通浏览复制代码
Acad::ErrorStatus safeExplode(const AcDbBlockReference* pRef,AcDbVoidPtrArray&entitySet)
{
AcDbBlockTableRecord* pBTR;
Acad::ErrorStatus es;
if ((es = acdbOpenAcDbObject((AcDbObject*&)pBTR, pRef->blockTableRecord(), AcDb::kForRead)) == Acad::eOk)
{
AcDbBlockTableRecordIterator* pIterator;
if (pBTR->newIterator(pIterator) == Acad::eOk)
{
AcGeMatrix3d xform = pRef->blockTransform();
AcGePoint3d pt3dBlkOrigin = pBTR->origin();
if (pt3dBlkOrigin != AcGePoint3d::kOrigin)
{
AcGeVector3d xformOrigin = xform.translation();
AcGeVector3d vectorOrigin(pt3dBlkOrigin.x,pt3dBlkOrigin.y,0.0);
vectorOrigin.transformBy(xform);
xformOrigin -= vectorOrigin;
xform.setTranslation(xformOrigin);
}
pIterator->start();
while (!pIterator->done())
{
AcDbEntity* pEntity;
if (pIterator->getEntity(pEntity, AcDb::kForRead) == Acad::eOk)
{
// If pEntity does not implement getTransformedCopy()
// or explode() methods, we should simply ignore
// that entity and continue to step into next entity
// instead of exit prematurely. Most operations such
// as BHATCH depends on complete iteration through
// the entire block entities.
AcDbEntity* pNewEntity;
AcDbText* pText =NULL;
if (pText=AcDbText::cast(pEntity))
es = AdskUtil::safeGetTransformedCopy(pText,xform, pNewEntity);
else
es = pEntity->getTransformedCopy(xform, pNewEntity);
if (es==Acad::eOk)
{
entitySet.append(pNewEntity);
}
else if (Acad::eExplodeBeforeTransform == es)
{
AcDbVoidPtrArray explSet;
if (Acad::eOk == pEntity->explode(explSet))
{
for (int i = 0; i < explSet.length(); i++)
{
AcDbEntity* pObj = (AcDbEntity*)explSet<i>;
if (Acad::eOk == pObj->getTransformedCopy( xform, pNewEntity))
{
entitySet.append(pNewEntity);
}
delete pObj;
}
}
}
else if (Acad::eCopyFailed == es)
{
AcDbVoidPtrArray explSet;
if (Acad::eOk == pEntity->explode(explSet))
{
for (int i = 0; i < explSet.length(); i++)
{
AcDbEntity* pObj = (AcDbEntity*)explSet<i>;
if (Acad::eOk == pObj->transformBy(xform))
{
entitySet.append(pObj);
}
}
}
}
pEntity->close();
}
pIterator->step();
}
delete pIterator;
}
pBTR->close();
}
return es;
} |
|