找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2356|回复: 20

[求助] 请问克隆(clone)的问题

[复制链接]
发表于 2017-4-5 20:41:39 | 显示全部楼层 |阅读模式

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

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

×
想实现这样的功能:把其他dwg文件的图形拷贝到当前dwg中
遇到的问题:画出来的线可以平移、旋转等操作,但是一旦用cad命令复制就会出现致命错误。
请问各位前辈,是哪里出了问题,或者用deepclone、wblock等代码应该如何实现?谢谢
代码如下:
for(pIter->start();!pIter->done();pIter->step())
    {
        if (pIter->getEntity(pEntity,AcDb::kForRead)!=Acad::eOk)
            continue;   
        pEntity->close();

        AcRxObject *pObject = pEntity->clone();
        if (pObject != NULL)
        {
            AcDbEntity *pOtherEnt = AcDbEntity::cast(pObject);
            if (pOtherEnt != NULL)
                AddEntityToDbsOLD(pOtherEnt);
        }
   
        continue;
}

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

已领礼包: 13个

财富等级: 恭喜发财

发表于 2017-4-5 23:55:39 | 显示全部楼层
下面代码是把一个外部DWG文件中的所有块定义(AcDbBlockTableRecord)克隆到当前数据库的代码,你可以借鉴下,如果你想拷贝其他的类型的,在判断实体类型的地方修改下就可以了,主要就是要把你要克隆的实体放到objIdArray数组里面。

  1. void XdDbUtils::CopyBlockTableRecordFromDwgFile(CString dwgFile,AcDbObjectIdArray &mId)
  2. {
  3.          Acad::ErrorStatus es;
  4.          AcDbDatabase *db = acdbHostApplicationServices()->workingDatabase();
  5.          //ACHAR dwgFile1[133];
  6.          CString dwgFile1;
  7.          ASSERT(dwgFile.CompareNoCase(_T("")) != 0);
  8.          acDocManager->lockDocument(curDoc(),AcAp::kWrite);
  9. #if (ADS < 20)
  10.          if (RTNORM == acedFindFile(dwgFile,dwgFile1.GetBuffer(_MAX_PATH))) //(FileExists(dwgFile) == TRUE)
  11. #else
  12.          if (RTNORM == acedFindFile(dwgFile,dwgFile1.GetBuffer(_MAX_PATH),_MAX_PATH)) //(FileExists(dwgFile) == TRUE)
  13. #endif
  14.          {
  15.                  dwgFile1.ReleaseBuffer();
  16.                  AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);
  17.                  if(Acad::eOk != (es = pDb->readDwgFile(dwgFile1))){
  18.                          acutPrintf(_T("Failed to reading dwg.Error:%d\n"),es);
  19.                          acDocManager->unlockDocument(curDoc());
  20.                          return;
  21.                  }
  22.                  AcDbBlockTable* pBT;
  23.                  es = pDb->getSymbolTable(pBT,AcDb::kForRead);
  24.                  if (es != Acad::eOk) {
  25.                          acutPrintf(_T("Error getting BlockTable of dwg.Error:%d\n"),es);
  26.                          acDocManager->unlockDocument(curDoc());
  27.                          return;
  28.                  }

  29.                  AcDbObjectId objId;
  30.                  AcDbObjectIdArray objIdArray;

  31.                  AcDbBlockTableIterator *pIT;
  32.                  es = pBT->newIterator(pIT);
  33.                  if (es != Acad::eOk) {
  34.                          acutPrintf(_T("Error iterating block table.Error:%d\n"),es);
  35.                          acDocManager->unlockDocument(curDoc());
  36.                          return;
  37.                  }

  38.                  for (; !pIT->done(); pIT->step()) {
  39.                          AcDbBlockTableRecord *pBlk;
  40.                          es = pIT->getRecord(pBlk,kForRead);
  41.                          if (es == Acad::eOk) {
  42.                                  if (!pBlk->isLayout() && !pBlk->isFromOverlayReference() && !pBlk->isFromExternalReference())
  43.                                  {
  44.                                          objIdArray.append(pBlk->objectId());
  45.                                  }
  46.                                  pBlk->close();
  47.                          }
  48.                  }
  49.                  delete pIT;
  50.                  pBT->close();

  51.                  //
  52.                  AcDbObjectId destBlkId;
  53.                  destBlkId = db->currentSpaceId();

  54.                  AcDbIdMapping idMap;
  55.                  idMap.setDestDb(db);
  56.                  es = db->wblockCloneObjects(objIdArray,destBlkId,idMap,AcDb::kDrcIgnore);
  57.                  if (es != Acad::eOk) {
  58.                          acutPrintf(_T("Failed wblockCloneObjects.Error:%d\n"),es);
  59.                          acDocManager->unlockDocument(curDoc());
  60.                          return;
  61.                  }
  62.                  AcDbIdMappingIter iter(idMap);
  63.                  for (iter.start(); !iter.done(); iter.next()) {
  64.                          AcDbIdPair pair;
  65.                          if (iter.getMap(pair)) {
  66.                                  AcDbObject *pEnt;
  67.                                  if (acdbOpenObject(pEnt,pair.value(),kForRead)==eOk)
  68.                                  {
  69.                                          if (pEnt->isKindOf(AcDbBlockTableRecord::desc()))
  70.                                          {
  71.                                                  mId.append(pair.value());
  72.                                          }
  73.                                          pEnt->close();
  74.                                  }
  75.                          }
  76.                  }
  77.                  acDocManager->unlockDocument(curDoc());
  78.                  delete pDb;
  79.          }
  80.          acDocManager->unlockDocument(curDoc());
  81. }

评分

参与人数 1D豆 +5 收起 理由
用途 + 5 很给力!经验;技术要点;资料分享奖!

查看全部评分

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

使用道具 举报

已领礼包: 13个

财富等级: 恭喜发财

发表于 2017-4-5 20:49:22 | 显示全部楼层
clone函数只能在同一个数据库中进行,从你描述,你应该是从别的数据库拷贝对象到当前数据库吧,

之前你应该用 AcDbDatabase::readDwgFile (...) 函数读入DWG从其他数据库,然后不同的数据库克隆对象,要用
AcDbDatabase::wblockCloneObjects Function
Acad::ErrorStatus
wblockCloneObjects(
AcDbObjectIdArray& objectIds,
AcDbObjectId& owner,
AcDbIdMapping& idMap,
AcDb::DuplicateRecordCloning drc,
bool deferXlation = false);
objectIdsInput array of objects to be deep cloned
ownerInput object ID of object to be the owner of the clones
idMapReturns array of AcDbIdPair objects to be used for translating object ID relationships
drcInput action for duplicate records
deferXlationInput Boolean indicating whether or not ID translation should be done
Clones all objects in the objectIds array and appends them to the container object specified by owner. The objects can be from multiple source databases, and must match the type of owner supplied, but must be from a different database than the owner object.

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

使用道具 举报

 楼主| 发表于 2017-4-5 21:05:53 | 显示全部楼层

谢谢,我修改了一下函数,但是这次图像都出不来了。刚学Arx不久,还请多多指点。
代码如下:
    AcDbObjectIdArray objArr;
    for(pIter->start();!pIter->done();pIter->step())
    {
        if (pIter->getEntity(pEntity,AcDb::kForRead)!=Acad::eOk)
            continue;   
        pEntity->close();

        AcDbObjectId objID;
        pIter->getEntityId(objID);
        objArr.append(objID);   
        continue;
    }

   AcDbDatabase * pDB=acdbHostApplicationServices()->workingDatabase();
   AcDbBlockTable *pBT1;
   pDB->getBlockTable(pBT1,AcDb::kForRead);

   AcDbIdMapping idMap;
   idMap.setDestDb(pDB);
   pDB->getSymbolTable(pBT1,AcDb::kForRead);
   pBT1->getAt(ACDB_MODEL_SPACE,pSpaceObjID);
   pBT1->close();
   Acad::ErrorStatus es=pDB->wblockCloneObjects(objArr,pSpaceObjID,idMap,AcDb::kDrcIgnore);
   AcDbEntity*pOtherEnt;
   if (acdbOpenObject(pOtherEnt,pSpaceObjID,AcDb::kForRead,Adesk::kFalse)==Acad::eOk)
      AddEntityToDbsOLD(pOtherEnt);


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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2017-4-5 21:13:12 | 显示全部楼层

你不是要从其他DWG文件里面读入图形插入到当前的图形吗?
上面代码怎么没看到你在哪里读入的其他图形DWG?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-5 21:23:56 | 显示全部楼层

用另外一个函数读的,通过AcDbBlockTableRecordIterator *pIter 传进来的数据

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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2017-4-5 21:31:46 | 显示全部楼层

你讀入的外部的DWG, 你是不能在當前數據庫裏面用這些迭代器進行操作的,你要直接把外部的DWG 克隆到當前的數據庫。
你還是把所有的代碼都貼上來吧,很多時候出問題不一定是你認爲的貼出的代碼。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-5 22:55:15 | 显示全部楼层

不好意思,刚家里停电了。代码比较多,粘不全,不过和这个函数有关的代码是这个:
void GetDwgData(CString pFile,int zbws,double zdgc,
                double zxgc,int fileposition,FILE *pInDex,int *MapFileSum)
{
    ACHAR mes[256];
    AcDbDatabase pDb(Adesk::kFalse);
   
    if((pDb.readDwgFile(pFile,_SH_DENYNO)) != Acad::eOk)//
    {
        _stprintf(mes,L"无法打开%s文件",pFile);
        ads_alert(mes);
        return;
    }

    AcDbBlockTable *pBlockTable;
    if((pDb.getBlockTable(pBlockTable,AcDb::kForRead)) != Acad::eOk)
    {
        ads_alert(L"get tablesymbol failed\n");
        return;
    }
    AcDbBlockTableRecord *pBloRec;
    if((pBlockTable->getAt(ACDB_MODEL_SPACE,pBloRec,AcDb::kForRead)) != Acad::eOk)
    {
        ads_alert(L"get block record failed\n");
        return;
    }
  pBlockTable->close();

    AcDbBlockTableRecordIterator *pIter;
    if((pBloRec->newIterator(pIter)) != Acad::eOk)
    {
        ads_alert(L"creat iterator fail");
        return;
    }
   
//----------------------   

    ACHAR fname[280];
    _stprintf(fname, L"C:\\Conlayername.txt");
    FILE *fpr;
   
    if(fpr!=NULL)fclose(fpr);
    {
        outdatalsd data;
        data.pIter=pIter;
        data.wnum = zbws;
        data.Getoffset(data.pIter);
    }
    delete pIter;
    pBloRec->close();

}

克隆的代码就是 data.Getoffset(data.pIter)  这个函数里面的

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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2017-4-5 23:34:50 | 显示全部楼层

看看这个帖子:  http://bbs.xdcad.net/thread-677988-1-1.html  关于模拟INSERT命令的实现的ARX代码。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2017-4-6 08:47:37 | 显示全部楼层

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

使用道具 举报

已领礼包: 21个

财富等级: 恭喜发财

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

使用道具 举报

已领礼包: 1304个

财富等级: 财源广进

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

使用道具 举报

 楼主| 发表于 2017-4-6 22:12:32 | 显示全部楼层

你好,你的代码很给力,不知是不是我使用方式不对,当前dwg里还是没有画出图像来,求继续指点,非常感谢!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 13个

财富等级: 恭喜发财

发表于 2017-4-6 22:30:19 | 显示全部楼层

都没出来,怎么就给力了

你试下什么都别改,调用那个函数,看看能把其他DWG里面的图块给插入到当前图里面不
其他的图里面一定要有INSERT实体。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-24 20:35 , Processed in 0.420591 second(s), 61 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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