找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 722|回复: 2

[分享] 在图形数据库之间传递数据 Wblock

[复制链接]

已领礼包: 13个

财富等级: 恭喜发财

发表于 2019-1-20 20:00:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 LoveArx 于 2019-1-21 00:52 编辑

(1)使用ObjectARX向导创建一个新工程,名称为Wblock.

添加普通类CBlockUtil,并在类中添加函数CopyBlockDefOtherDwg,用于将其他Dwg文件 中的块定义赋值到当前图形数据库。

实现代码:

  1. AcDbObjectId CBlockUtil::CopyBlockDefFromOtherDwg(const TCHAR* fileName,
  2.         const TCHAR* blkDefName)
  3. {
  4.         AcDbObjectId blockRefId = AcDbObjectId::kNull;
  5.                                 //AcDbObjectId :: kNull表示当前DWG中不存在对象(图层)

  6.         //使用_SH_DENYNO参数打开图形(只读打开),允许其他用户读写文件
  7.         AcDbDatabase* pSourceDwg = new AcDbDatabase(false);
  8.         Acad::ErrorStatus es = pSourceDwg->readDwgFile(fileName,
  9.                 static_cast<AcDbDatabase::OpenMode>(_SH_DENYNO));
  10.         if (es != Acad::eOk)
  11.         {
  12.                 delete pSourceDwg;
  13.                 pSourceDwg = NULL;

  14.                 acutPrintf(TEXT("\n读入dwg图形错误,图形名称:%s"), fileName);
  15.                 return blockRefId;
  16.         }

  17.         //打开外部图形数据库的块表,寻找给定名称的块表记录
  18.         AcDbBlockTable* pBlkTable = NULL;
  19.         es = pSourceDwg->getBlockTable(pBlkTable, AcDb::kForRead);
  20.                          //以只读模式打开数据库的块表,pBlkTable获得块表地址
  21.         assert(es == Acad::eOk);
  22.         bool bRet = false;

  23.         if (pBlkTable->has(blkDefName))  //不存在指定的图块
  24.         {
  25.                 AcDbObjectId destBlkDefId; //指定图块的块表记录Id
  26.                 es = pBlkTable->getAt(blkDefName, destBlkDefId);

  27.                 //把指定的图块输出到一个临时的图形数据库
  28.                 AcDbDatabase *pTempDb = NULL;  //注意:这里千万不能new
  29.                 es = pSourceDwg->wblock(pTempDb, destBlkDefId);//创建一个新的数据库对象,pTempDb指向它
  30.                 assert(es == Acad::eOk);

  31.                 //把临时图形数据库作为插入块插入到当前dwg
  32.                 AcDbDatabase* pCurDb = acdbHostApplicationServices()->workingDatabase();
  33.                 es = pCurDb->insert(blockRefId, blkDefName, pTempDb);//由pDb指向的数据库中的所有
  34.             //模型空间实体都被复制到新的块表记录中,新的块表记录名称为blkDefName,Id为blockRefId
  35.                 assert(es == Acad::eOk);
  36.                 delete pTempDb;
  37.                 pTempDb = NULL;
  38.         }
  39.         else
  40.         {
  41.                 acutPrintf(TEXT("\n给定的DWG文件中,不存在指定名称的块表记录."));
  42.         }
  43.         pBlkTable->close();

  44.         delete pSourceDwg;
  45.         pSourceDwg = NULL;

  46.         return blockRefId;
  47. }

(2)在CBlockUtil类中添加函数InsertDwgBlockDef,用于将指定的整个DWG文件作为图块加入到当前图形文件中作为块定义。

实现代码:

InsertDwgBlockDef函数的声明:

  1.         // 将DWG文件作为块定义加入到指定的图形数据库
  2.         // bOverwriteIfExist: 如果指定的图形数据库中已经定义了同名的块,是否覆盖原有的定义
  3.         static AcDbObjectId InsertDwgBlockDef(const TCHAR* dwgFileName,
  4.               const TCHAR* blkName, bool bOverwriteIfExist,
  5.                       AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());
  6. InsertDwgBlockDef函数的实现:

  7.    AcDbObjectId CBlockUtil::InsertDwgBlockDef(const TCHAR* dwgFileName,
  8.         const TCHAR* blkName, bool bOverwriteIfExist, AcDbDatabase *pDb)
  9. {
  10.         //是否包含指定名称的块定义
  11.         AcDbObjectId blkDefId = GetBlkDefId(blkName, pDb);
  12.         if (blkDefId.isNull() || bOverwriteIfExist)
  13.         {
  14.                 if (_taccess(dwgFileName, 0) != -1)//如果指定的文件不存在,返回-1
  15.                 {
  16.                         AcDbDatabase *pBlkDb = new AcDbDatabase(false);
  17.                         Acad::ErrorStatus es = pBlkDb->readDwgFile(dwgFileName,
  18.                                               static_cast<AcDbDatabase::OpenMode>(_SH_DENYNO));
  19.                         if (es == Acad::eOk)
  20.                         {
  21.                                 es = pDb->insert(blkDefId, blkName, pBlkDb);//在执行此insert函数的数据库中
  22.                                               //创建新的块表记录;由pBlkDb指向的数据库中的所有模型空间实体都
  23.                                               //被复制到新的块表记录中,名称为blkName,Id为blkDefId
  24.                                 if (es != Acad::eOk)
  25.                                 {
  26.                                         CString strMsg;
  27.                                         strMsg.Format(TEXT("CBlockUtil::InsertDwgBlockDef函数,insert失败:%d."),
  28.                                                 (int)es);
  29.                                         AfxMessageBox(strMsg);
  30.                                 }
  31.                         }
  32.                         else
  33.                         {
  34.                                 CString strMsg;
  35.                                 strMsg.Format(TEXT("CBlockUtil::InsertDwgBlockDef函数,readDwg File失败:%d."),
  36.                                         (int)es);
  37.                                 AfxMessageBox(strMsg);
  38.                         }
  39.                         delete pBlkDb;
  40.                 }
  41.                 else
  42.                 {
  43.                         AfxMessageBox(TEXT("CBlockUtil::InsertDwgBlockDef函数,未找到指定的图块文件."));
  44.                 }
  45.         }
  46.         return blkDefId;
  47. }

其中,

GetBlkDefId函数的声明:

  1.         // 获得指定名称的块定义
  2.         static AcDbObjectId GetBlkDefId(const TCHAR* blkDefName,
  3. AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());
  4. GetBlkDefId函数的实现:

  5. // 获得指定名称的块定义
  6. AcDbObjectId CBlockUtil::GetBlkDefId(const TCHAR* blkDefName, AcDbDatabase *pDb)
  7. {
  8.         AcDbBlockTable* pBlockTable = NULL;
  9.         Acad::ErrorStatus es = pDb->getBlockTable(pBlockTable, AcDb::kForRead);
  10.         AcDbObjectId blkDefId;
  11.         es = pBlockTable->getAt(blkDefName, blkDefId);
  12.         pBlockTable->close();

  13.         if (es == Acad::eOk)
  14.         {
  15.                 return blkDefId;
  16.         }
  17.         else
  18.         {
  19.                 return AcDbObjectId::kNull;
  20.         }
  21. }

(3)注册函命令InsertBlkRefFromOtherDwg,将外部图形文件中的块定义复制到当前图形文件,然后在图形窗口中插入这个块定义的块参照。

注册函数InsertBlkRefFromOtherDwg的实现代码:

  1. static void AAAMyGroupInsertBlkRefFromOtherDwg() {
  2.                 CString fileName = TEXT("C:\\'包含图块.dwg");
  3.                 if (_taccess(fileName, 0) != -1)
  4.                 {
  5.                         AcDbObjectId blkDefId = CBlockUtil::CopyBlockDefFromOtherDwg(fileName,
  6.                                 TEXT("测试图块"));
  7.                         if (blkDefId.isValid())
  8.                         {
  9.                                 CBlockUtil::InsertBlockRef(blkDefId, AcGePoint3d(100, 100, 0), 1, 0);
  10.                         }
  11.                 }
  12.                 else
  13.                 {
  14.                         acutPrintf(TEXT("\n指定的图形文件不存在"));
  15.                 }

  16.         }

其中,



InsertBlockRef函数的声明:

  1.         // 插入块参照
  2.         static AcDbObjectId InsertBlockRef(AcDbObjectId blkDefId, const AcGePoint3d &insertPoint,
  3. double scale = 1, double rotation = 0);
  4. InsertBlockRef函数的实现:

  5. // 插入块参照
  6. AcDbObjectId CBlockUtil::InsertBlockRef(AcDbObjectId blkDefId, const AcGePoint3d &insertPoint, double scale,
  7.         double rotation)
  8. {
  9.         // 设置图块的插入点、旋转角度、比例等等
  10.         AcDbBlockReference *pBlkRef = new AcDbBlockReference(insertPoint, blkDefId);
  11.         pBlkRef->setRotation(rotation);
  12.         SetScaleFactor(pBlkRef, scale);

  13.         // 把新建的图块参照实体加入到新建的块表记录中,并取得插入图块的实体Id,用于返回值
  14.         return CDwgDatabaseUtil::PostToModelSpace(pBlkRef);
  15. }


SetScaleFactor函数的声明:


  1.         // 设置块参照的缩放比例
  2.         static void SetScaleFactor(AcDbBlockReference *pBlkRef, double scale);
  3. SetScaleFactor函数的实现:  

  4. // 修改块参照的插入比例
  5. void CBlockUtil::SetScaleFactor( AcDbBlockReference *pBlkRef, double scale )
  6. {
  7.         assert (pBlkRef);
  8.         
  9.         AcGeScale3d geScale(scale, scale, scale);
  10.         pBlkRef->setScaleFactors(geScale);
  11. }



PostToModelSpace函数的声明:

  1.         // 将实体添加到模型空间
  2.         static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt,
  3.      AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());

PostToModelSpace函数的声明:


  1. AcDbObjectId CDwgDatabaseUtil::PostToModelSpace(AcDbEntity *pEnt, AcDbDatabase *pDb)
  2. {
  3.         // 检查输入参数的有效性
  4.         assert(pEnt);                // 等效于assert (pEnt != NULL);

  5.                                                 // 获得当前图形数据库的块表
  6.         AcDbBlockTable *pBlkTbl = NULL;
  7.         pDb->getBlockTable(pBlkTbl, AcDb::kForRead);

  8.         // 获得模型空间对应的块表记录
  9.         AcDbBlockTableRecord *pBlkTblRcd = NULL;
  10.         pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd, AcDb::kForWrite);
  11.         pBlkTbl->close();

  12.         // 将实体添加到模型空间的块表记录
  13.         AcDbObjectId entId;
  14.         Acad::ErrorStatus es = pBlkTblRcd->appendAcDbEntity(entId, pEnt);
  15.         if (es != Acad::eOk)
  16.         {
  17.                 pBlkTblRcd->close();
  18.                 delete pEnt;        // 添加失败时,要delete
  19.                 pEnt = NULL;

  20.                 return AcDbObjectId::kNull;
  21.         }

  22.         // 关闭模型空间块表记录和实体
  23.         pBlkTblRcd->close();
  24.         pEnt->close();

  25.         return entId;
  26. }


(4)注册命令InsertDwgBlockRef,将某个DWG文件作为图块插入到当前的模型空间。

实现代码为:

注册函数InsertDwgBlockRef 的实现:

  1.         static void AAAMyGroupInsertDwgBlockRef() {
  2.                 CString fileName = TEXT("C:\\作为图块的文件.dwg");
  3.                 if (_taccess(fileName, 0) != -1)
  4.                 {
  5.                         AcDbObjectId blkDefId = CBlockUtil::InsertDwgBlockDef(fileName,
  6.                                 TEXT("外部DWG图块"), true);
  7.                         if (blkDefId.isValid())
  8.                         {
  9.                                 CBlockUtil::InsertBlockRef(blkDefId, AcGePoint3d(200, 100, 0), 1, 0);
  10.                         }
  11.                 }
  12.                 else
  13.                 {
  14.                         acutPrintf(TEXT("\n指定的图形文件不存在."));
  15.                 }

  16.         }



思路总结:
在图形数据库之间传递数据 Wblock-1.jpg

完整的项目源代码:

   
请点击此处下载

请先注册会员后在进行下载

已注册会员,请先登录后下载

文件名称:代码(提取码:hni9 ) 
下载次数:16  文件大小:0 Bytes  售价:1D豆 [记录]
下载权限: 不限 以上  [免费赚D豆]




论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 960个

财富等级: 财运亨通

发表于 2019-1-21 07:41:10 | 显示全部楼层
谢谢楼主分享知识
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 5060个

财富等级: 富甲天下

发表于 2019-1-21 12:53:23 | 显示全部楼层
可以保存为低版本吗版主?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-20 10:02 , Processed in 0.337445 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表