(1)使用ObjectARX向导创建一个新工程,名称为Wblock.
添加普通类CBlockUtil,并在类中添加函数CopyBlockDefOtherDwg,用于将其他Dwg文件 中的块定义赋值到当前图形数据库。
实现代码:
AcDbObjectId CBlockUtil::CopyBlockDefFromOtherDwg(const TCHAR* fileName,
const TCHAR* blkDefName)
{
AcDbObjectId blockRefId = AcDbObjectId::kNull;
//AcDbObjectId :: kNull表示当前DWG中不存在对象(图层)
//使用_SH_DENYNO参数打开图形(只读打开),允许其他用户读写文件
AcDbDatabase* pSourceDwg = new AcDbDatabase(false);
Acad::ErrorStatus es = pSourceDwg->readDwgFile(fileName,
static_cast(_SH_DENYNO));
if (es != Acad::eOk)
{
delete pSourceDwg;
pSourceDwg = NULL;
acutPrintf(TEXT("\n读入dwg图形错误,图形名称:%s"), fileName);
return blockRefId;
}
//打开外部图形数据库的块表,寻找给定名称的块表记录
AcDbBlockTable* pBlkTable = NULL;
es = pSourceDwg->getBlockTable(pBlkTable, AcDb::kForRead);
//以只读模式打开数据库的块表,pBlkTable获得块表地址
assert(es == Acad::eOk);
bool bRet = false;
if (pBlkTable->has(blkDefName)) //不存在指定的图块
{
AcDbObjectId destBlkDefId; //指定图块的块表记录Id
es = pBlkTable->getAt(blkDefName, destBlkDefId);
//把指定的图块输出到一个临时的图形数据库
AcDbDatabase *pTempDb = NULL; //注意:这里千万不能new
es = pSourceDwg->wblock(pTempDb, destBlkDefId);//创建一个新的数据库对象,pTempDb指向它
assert(es == Acad::eOk);
//把临时图形数据库作为插入块插入到当前dwg
AcDbDatabase* pCurDb = acdbHostApplicationServices()->workingDatabase();
es = pCurDb->insert(blockRefId, blkDefName, pTempDb);//由pDb指向的数据库中的所有
//模型空间实体都被复制到新的块表记录中,新的块表记录名称为blkDefName,Id为blockRefId
assert(es == Acad::eOk);
delete pTempDb;
pTempDb = NULL;
}
else
{
acutPrintf(TEXT("\n给定的DWG文件中,不存在指定名称的块表记录."));
}
pBlkTable->close();
delete pSourceDwg;
pSourceDwg = NULL;
return blockRefId;
}
(2)在CBlockUtil类中添加函数InsertDwgBlockDef,用于将指定的整个DWG文件作为图块加入到当前图形文件中作为块定义。
实现代码:
InsertDwgBlockDef函数的声明:
// 将DWG文件作为块定义加入到指定的图形数据库
// bOverwriteIfExist: 如果指定的图形数据库中已经定义了同名的块,是否覆盖原有的定义
static AcDbObjectId InsertDwgBlockDef(const TCHAR* dwgFileName,
const TCHAR* blkName, bool bOverwriteIfExist,
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());
InsertDwgBlockDef函数的实现:
AcDbObjectId CBlockUtil::InsertDwgBlockDef(const TCHAR* dwgFileName,
const TCHAR* blkName, bool bOverwriteIfExist, AcDbDatabase *pDb)
{
//是否包含指定名称的块定义
AcDbObjectId blkDefId = GetBlkDefId(blkName, pDb);
if (blkDefId.isNull() || bOverwriteIfExist)
{
if (_taccess(dwgFileName, 0) != -1)//如果指定的文件不存在,返回-1
{
AcDbDatabase *pBlkDb = new AcDbDatabase(false);
Acad::ErrorStatus es = pBlkDb->readDwgFile(dwgFileName,
static_cast(_SH_DENYNO));
if (es == Acad::eOk)
{
es = pDb->insert(blkDefId, blkName, pBlkDb);//在执行此insert函数的数据库中
//创建新的块表记录;由pBlkDb指向的数据库中的所有模型空间实体都
//被复制到新的块表记录中,名称为blkName,Id为blkDefId
if (es != Acad::eOk)
{
CString strMsg;
strMsg.Format(TEXT("CBlockUtil::InsertDwgBlockDef函数,insert失败:%d."),
(int)es);
AfxMessageBox(strMsg);
}
}
else
{
CString strMsg;
strMsg.Format(TEXT("CBlockUtil::InsertDwgBlockDef函数,readDwg File失败:%d."),
(int)es);
AfxMessageBox(strMsg);
}
delete pBlkDb;
}
else
{
AfxMessageBox(TEXT("CBlockUtil::InsertDwgBlockDef函数,未找到指定的图块文件."));
}
}
return blkDefId;
}
其中,
GetBlkDefId函数的声明:
// 获得指定名称的块定义
static AcDbObjectId GetBlkDefId(const TCHAR* blkDefName,
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());
GetBlkDefId函数的实现:
// 获得指定名称的块定义
AcDbObjectId CBlockUtil::GetBlkDefId(const TCHAR* blkDefName, AcDbDatabase *pDb)
{
AcDbBlockTable* pBlockTable = NULL;
Acad::ErrorStatus es = pDb->getBlockTable(pBlockTable, AcDb::kForRead);
AcDbObjectId blkDefId;
es = pBlockTable->getAt(blkDefName, blkDefId);
pBlockTable->close();
if (es == Acad::eOk)
{
return blkDefId;
}
else
{
return AcDbObjectId::kNull;
}
}
(3)注册函命令InsertBlkRefFromOtherDwg,将外部图形文件中的块定义复制到当前图形文件,然后在图形窗口中插入这个块定义的块参照。
注册函数InsertBlkRefFromOtherDwg的实现代码:
static void AAAMyGroupInsertBlkRefFromOtherDwg() {
CString fileName = TEXT("C:\\'包含图块.dwg");
if (_taccess(fileName, 0) != -1)
{
AcDbObjectId blkDefId = CBlockUtil::CopyBlockDefFromOtherDwg(fileName,
TEXT("测试图块"));
if (blkDefId.isValid())
{
CBlockUtil::InsertBlockRef(blkDefId, AcGePoint3d(100, 100, 0), 1, 0);
}
}
else
{
acutPrintf(TEXT("\n指定的图形文件不存在"));
}
}
其中,
①
InsertBlockRef函数的声明:
// 插入块参照
static AcDbObjectId InsertBlockRef(AcDbObjectId blkDefId, const AcGePoint3d &insertPoint,
double scale = 1, double rotation = 0);
InsertBlockRef函数的实现:
// 插入块参照
AcDbObjectId CBlockUtil::InsertBlockRef(AcDbObjectId blkDefId, const AcGePoint3d &insertPoint, double scale,
double rotation)
{
// 设置图块的插入点、旋转角度、比例等等
AcDbBlockReference *pBlkRef = new AcDbBlockReference(insertPoint, blkDefId);
pBlkRef->setRotation(rotation);
SetScaleFactor(pBlkRef, scale);
// 把新建的图块参照实体加入到新建的块表记录中,并取得插入图块的实体Id,用于返回值
return CDwgDatabaseUtil::PostToModelSpace(pBlkRef);
}
②
SetScaleFactor函数的声明:
// 设置块参照的缩放比例
static void SetScaleFactor(AcDbBlockReference *pBlkRef, double scale);
SetScaleFactor函数的实现:
// 修改块参照的插入比例
void CBlockUtil::SetScaleFactor( AcDbBlockReference *pBlkRef, double scale )
{
assert (pBlkRef);
AcGeScale3d geScale(scale, scale, scale);
pBlkRef->setScaleFactors(geScale);
}
③
PostToModelSpace函数的声明:
// 将实体添加到模型空间
static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt,
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());
PostToModelSpace函数的声明:
AcDbObjectId CDwgDatabaseUtil::PostToModelSpace(AcDbEntity *pEnt, AcDbDatabase *pDb)
{
// 检查输入参数的有效性
assert(pEnt); // 等效于assert (pEnt != NULL);
// 获得当前图形数据库的块表
AcDbBlockTable *pBlkTbl = NULL;
pDb->getBlockTable(pBlkTbl, AcDb::kForRead);
// 获得模型空间对应的块表记录
AcDbBlockTableRecord *pBlkTblRcd = NULL;
pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd, AcDb::kForWrite);
pBlkTbl->close();
// 将实体添加到模型空间的块表记录
AcDbObjectId entId;
Acad::ErrorStatus es = pBlkTblRcd->appendAcDbEntity(entId, pEnt);
if (es != Acad::eOk)
{
pBlkTblRcd->close();
delete pEnt; // 添加失败时,要delete
pEnt = NULL;
return AcDbObjectId::kNull;
}
// 关闭模型空间块表记录和实体
pBlkTblRcd->close();
pEnt->close();
return entId;
}
(4)注册命令InsertDwgBlockRef,将某个DWG文件作为图块插入到当前的模型空间。
实现代码为:
注册函数InsertDwgBlockRef 的实现:
static void AAAMyGroupInsertDwgBlockRef() {
CString fileName = TEXT("C:\\作为图块的文件.dwg");
if (_taccess(fileName, 0) != -1)
{
AcDbObjectId blkDefId = CBlockUtil::InsertDwgBlockDef(fileName,
TEXT("外部DWG图块"), true);
if (blkDefId.isValid())
{
CBlockUtil::InsertBlockRef(blkDefId, AcGePoint3d(200, 100, 0), 1, 0);
}
}
else
{
acutPrintf(TEXT("\n指定的图形文件不存在."));
}
}
思路总结:
完整的项目源代码:
https://pan.baidu.com/s/1nIM7NcpE__IZ8n1GTga6AA
<未完待续>