问题
先简单记录一下,在CAD中如何使用代码添加PDF底图参照。后面再补充细节。
解决
#include "adsmigr.h"
#include "acutmigr.h"
#include "dbapserv.h"
#include "afxstr.h"
#include "boost/filesystem.hpp"
#include "acdocman.h"
#include "dbunderlaydef.h"
#include "dbunderlayref.h"
#include "dbobjptr.h"
void attachPdf()
{
CString sPdfPath;
CString sPdfName, sPassword;
int nPage;
AcGePoint3d ptInsert;
double dScale, dRotate;
if (sPdfName.IsEmpty())
{
acutPrintf(_T("\n PDF参照名称为空"));
return;
}
if (!boost::filesystem::exists(sPdfPath.GetString()))
{
acutPrintf(_T("\n PDF路径: %s 不存在"), sPdfPath);
return;
}
AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, false);
// PDF字典
CString sPdfDict = AcDbUnderlayDefinition::dictionaryKey(AcDbPdfDefinition::desc());
AcDbObjectId pdfDictId = getDictionaryId(pDb, sPdfDict, true);
AcDbObjectId pdfDefId = AcDbObjectId::kNull;
CreatePDFDefinition(pdfDefId, pDb, pdfDictId, sPdfPath, sPdfName, nPage, sPassword);
CreatePdfReference(pDb, pdfDefId, ptInsert, dScale, dRotate);
}
AcDbObjectId getDictionaryId(AcDbDatabase* pDb, const CString& sDicName, bool bCreate = true)
{
AcDbObjectId dictId = AcDbObjectId::kNull;
if (!pDb)
return dictId;
AcDbDictionary* pNamedObj;
Acad::ErrorStatus es = pDb->getNamedObjectsDictionary(pNamedObj, AcDb::kForRead);
if (es != Acad::eOk)
return dictId;
es = pNamedObj->getAt(sDicName, dictId);
if (es == Acad::eKeyNotFound && bCreate)
{
AcDbDictionary* pDictary = new AcDbDictionary;
pNamedObj->setAt(sDicName, pDictary, dictId);
}
pNamedObj->close();
return dictId;
}
void CreatePDFDefinition(AcDbObjectId& pdfDefId, AcDbDatabase* pDb, const AcDbObjectId& pdfDictId, const CString& sPdfPath, const CString& sPdfName, int nPage, const CString& sPassword)
{
if (!pDb)
return;
AcDbDictionaryPointer pPdfDictionary(pdfDictId, AcDb::kForWrite);
if (pPdfDictionary.openStatus() != Acad::eOk)
{
acutPrintf(_T("\n 打开字典失败"));
return;
}
// PDF定义对象
AcDbPdfDefinition* pPdfDef = new AcDbPdfDefinition();
Acad::ErrorStatus es = pPdfDef->setSourceFileName(sPdfPath);
if (es != Acad::eOk)
{
delete pPdfDef;
acutPrintf(_T("\n 设置PDF路径失败"));
return;
}
CString sPage;
sPage.Format(_T("%d"), nPage);
pPdfDef->setItemName(sPage);// 设置PDF页数
es = pPdfDef->load(sPassword);
if (es != Acad::eOk)
{
delete pPdfDef;
acutPrintf(_T("\n 加载PDF指定页失败"));
return;
}
// 创建PDF项
CString sKey;
sKey.Format(_T("%s-%s"), sPdfName, sPage);
AcDbObjectId pdfDefId = AcDbObjectId::kNull;
if (!pPdfDictionary->has(sKey))
pPdfDictionary->setAt(sKey, pPdfDef, pdfDefId);
else
{
pPdfDictionary->getAt(sKey, (AcDbObject*&)pPdfDef, AcDb::kForWrite);
pdfDefId = pPdfDef->objectId();
}
pPdfDictionary.close();
pPdfDef->close();
}
void CreatePdfReference(AcDbDatabase* pDb, const AcDbObjectId& pdfDefId, const AcGePoint3d& ptInsert, double dScale, double dRotate)
{
if (!pDb)
return;
// PDF引用
AcDbPdfReference* pPdfReference = new AcDbPdfReference;
pPdfReference->setDefinitionId(pdfDefId);
pPdfReference->setPosition(ptInsert);
pPdfReference->setScaleFactors(AcGeScale3d(dScale));
pPdfReference->setRotation(dRotate);
pPdfReference->setDatabaseDefaults(pDb);
pPdfReference->setFade(25); // 设置淡入度
pPdfReference->setContrast(88); // 设置对比度
pPdfReference->setIsMonochrome(true); // 设置单色
AcDbObjectPointer<AcDbBlockTableRecord> pRec(pDb->currentSpaceId(), AcDb::kForWrite);
if (pRec.openStatus() != Acad::eOk)
{
delete pPdfReference;
return;
}
AcDbObjectId pdfReferId = AcDbObjectId::kNull;
Acad::ErrorStatus es = pRec->appendAcDbEntity(pdfReferId, pPdfReference);
if (es != Acad::eOk)
{
pRec->close();
delete pPdfReference;
return;
}
pRec->close();
pPdfReference->close();
return;
}