AcDbBlockReference::explode 失败
AcDbBlockReference::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;
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;
if (Acad::eOk == pObj->transformBy(xform))
{
entitySet.append(pObj);
}
}
}
}
pEntity->close();
}
pIterator->step();
}
delete pIterator;
}
pBTR->close();
}
return es;
}
请问safeGetTransformedCopy这个函数是自定义的吗?源码可否发一下 革天明 发表于 2022-11-5 22:28
请问safeGetTransformedCopy这个函数是自定义的吗?源码可否发一下
对AcDbText的安全的transformedCopy方法
Acad::ErrorStatus XdDbUtils::safeGetTransformedCopy(const AcDbText* pText,
const AcGeMatrix3d xform, AcDbEntity*& pNewEntity)
{
static AcDbText text;
Acad::ErrorStatus es;
text.copyFrom(pText);
AcGePoint3d posorig(text.position());
AcGePoint3d alignorig(text.alignmentPoint());
AcGePoint3d pos,align;
AcGeVector3d norm(text.normal());
acdbWcs2Ecs(asDblArray(posorig),asDblArray(pos),asDblArray(norm),
Adesk::kFalse);
double elev = pos.z;
if (fabs(elev)>1E-10)
{
pos.z = 0;
align.z =0;
acdbEcs2Wcs(asDblArray(pos),asDblArray(pos),asDblArray(norm),
Adesk::kFalse);
acdbEcs2Wcs(asDblArray(align),asDblArray(align),asDblArray(norm),
Adesk::kFalse);
text.setPosition(pos);
text.setAlignmentPoint(align);
}
if ((es = text.getTransformedCopy(xform,pNewEntity))==Acad::eOk)
{
AcDbText* pNewText = NULL;
if ((pNewText = AcDbText::cast(pNewEntity)) && fabs(elev)>1E-10)
{
posorig.transformBy(xform);
alignorig.transformBy(xform);
pNewText->setPosition(posorig);
pNewText->setAlignmentPoint(alignorig);
}
}
return es;
}
XDSoft 发表于 2023-11-14 03:08
对AcDbText的安全的transformedCopy方法
谢谢回复,我学习一下
页:
[1]