- UID
- 5043
- 积分
- 1347
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-5-13
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 LoveArx 于 2019-1-21 00:52 编辑
(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<AcDbDatabase::OpenMode>(_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<AcDbDatabase::OpenMode>(_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指定的图形文件不存在."));
- }
- }
思路总结:
完整的项目源代码:
|
|