将当前dwg内的对象复制到另一个dwg文件中

作者: admin 分类: C++,CAD,ObjectARX 发布时间: 2020-08-30 15:14

转自:https://blog.csdn.net/TXH0001/article/details/6384253?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

 //将当前dwg内的对象复制到另一个dwg文件中
 AcDbDatabase * pDB=acdbHostApplicationServices()->workingDatabase();
 AcDbBlockTable *pBT1;
 pDB->getBlockTable(pBT1,AcDb::kForRead);
 
    AcDbBlockTableRecord *pBTR1;
 pBT1->getAt(ACDB_MODEL_SPACE,pBTR1,AcDb::kForRead);
 AcDbBlockTableRecordIterator * pBTRIt;
 AcDbObjectIdArray objArr;
 AcDbIdMapping idMap;
 
 pBTR1->newIterator(pBTRIt);
 pBTRIt->start();
 
 for (;!pBTRIt->done();pBTRIt->step())
 {
  AcDbObjectId objID;
  pBTRIt->getEntityId(objID);
  objArr.append(objID);  

//下面的代码要执行,到时整合
//    for ( ; !pIT->done(); pIT->step()) {
//     if (Acad::eOk == pIT->getEntityId( id )) {
//      list.append( id );
//      
//      // There is a bug in ARX that causes extension dictionaries
//      // to appear to be soft owners of their contents.  This causes
//      // the contents to be skipped during wblock.  To fix this we
//      // must explicitly tell the extension dictionary to be a hard
//      // owner of it's entries.
//      //
//      AcDbEntity *pEnt;
//      if ( Acad::eOk == pIT->getEntity(pEnt, AcDb::kForRead)) {
//       AcDbObjectId obj;
//       if ((obj = pEnt->extensionDictionary())
//        != AcDbObjectId::kNull)
//       {
//        AcDbDictionary *pDict = NULL;
//        acdbOpenObject(pDict, obj, AcDb::kForWrite);
//        if (pDict) {
//         pDict->setTreatElementsAsHard(Adesk::kTrue);
//         pDict->close();
//        }
//       }
//       pEnt->close();
//      }
//     }
//   }

 }
 delete pBTRIt;
 pBTR1->close();
 pBT1->close();
 
 AcDbDatabase* pTempDb=new AcDbDatabase();
 
 idMap.setDestDb(pTempDb);
 pTempDb->getSymbolTable(pBT1,AcDb::kForRead);
 Acad::ErrorStatus e;
 AcDbBlockTableRecord * pBTR2;
 AcDbObjectId pSpaceObjID;
 pBT1->getAt(ACDB_MODEL_SPACE,pSpaceObjID);
 pBT1->close();
 // pSpaceObjID=getBlockId(ACDB_PAPER_SPACE);
 
  e=pTempDb->wblockCloneObjects(objArr,pSpaceObjID,idMap,AcDb::kDrcIgnore);
  pTempDb->saveAs(_T("c:\\aaa.dwg"));
  delete  pTempDb;

https://blog.csdn.net/he_zhidan/article/details/78890389

从AcDbDatabase复制部分对象到新AcDbDatabase
AcDbDatabase* pCur = acdbHostApplicationServices()->workingDatabase();
 AcDbDatabase* pOut = NULL;
 pCur->wblock(pOut,outObjIds,Cad::CDoublePoint());


https://www.cnblogs.com/edata/p/10777134.html

使用wblockCloneObjects从后台读取dwg文件复制实体到当前数据库

AcDbDatabase *pNewDb=new AcDbDatabase(Adesk::kFalse);        
        if (pNewDb == NULL)
        {
            return;
        }
        Acad::ErrorStatus es= pNewDb->readDwgFile(_T("D:\\123.dwg"));
        if (Acad::eOk != es || NULL == pNewDb)
        {
            acutPrintf(_T("\n打开dwg文件失败,错误码:%s"),acadErrorStatusText(es));
            return;
        }
        AcDbObjectIdArray objIdArray;
        AcDbBlockTable *pBlkTbl=NULL;
        es= pNewDb->getBlockTable(pBlkTbl,AcDb::kForRead);
        if (Acad::eOk != es || NULL == pBlkTbl)
        {
            acutPrintf(_T("\n获取源数据库块表失败,错误码:%s"),acadErrorStatusText(es));
            delete pNewDb;
            pNewDb=NULL;
            return;
        }
        AcDbBlockTableRecord *pMsBlkRcd=NULL;
        es= pBlkTbl->getAt(ACDB_MODEL_SPACE,pMsBlkRcd,AcDb::kForRead);
        pBlkTbl->close();
        if (Acad::eOk != es || NULL == pMsBlkRcd)
        {
            acutPrintf(_T("\n获取源数据库模型空间块表记录失败,错误码:%s"),acadErrorStatusText(es));
            delete pNewDb;
            pNewDb=NULL;
            return;
        }
        //遍历源数据库模型空间块记录中的实体
        AcDbBlockTableRecordIterator *pIter=NULL;
        pMsBlkRcd->newIterator(pIter);
        pMsBlkRcd->close();
        AcDbObjectId objId;        
        for (pIter->start();!pIter->done();pIter->step())
        {
            pIter->getEntityId(objId);
            objIdArray.append(objId);
            //将扩展字典改为硬拥有,否则写块出去后会丢失
            AcDbEntity *pEnt=NULL;
            es = pIter->getEntity(pEnt,AcDb::kForWrite);
            if (Acad::eOk == es)
            {
                AcDbObjectId dicId= pEnt->extensionDictionary();
                if (AcDbObjectId::kNull != dicId)
                {
                    AcDbObjectPointer<AcDbDictionary> pDic(dicId,AcDb::kForWrite);
                    if(Acad::eOk == pDic.openStatus())
                    {
                        pDic->setTreatElementsAsHard(Adesk::kTrue);
                        pDic->close();
                    }
                }
                pEnt->close();
            }
        }
        delete pIter;        
        //检查objectId
        if (objIdArray.isEmpty())
        {
            acutPrintf(_T("\n克隆失败,源数据库的模型空间没有实体!"));
            delete pNewDb;
            pNewDb=NULL;
            return;
        }
        AcDbIdMapping idMap; 
        AcDbDatabase *pDb= acdbHostApplicationServices()->workingDatabase();
        //获取当前数据库的空间ID
        AcDbObjectId mSpaceId= pDb->currentSpaceId();
        //写块克隆 忽略重定义模式
        es =  pNewDb->wblockCloneObjects(objIdArray,mSpaceId,idMap,AcDb::kDrcIgnore);
        if (Acad::eOk != es)
        {
            acutPrintf(_T("\ndeepCloneObjects失败错误码:%s"),acadErrorStatusText(es));
            delete pNewDb;
            pNewDb=NULL;
            return;
        }
        //删除临时数据库
        delete pNewDb;
        pNewDb=NULL;
        
    
        
        AcDbIdPair IdPair;
        AcDbObjectIdArray arrID2; 
        //获取克隆后的和原id匹配的对象的objectid,克隆idmap是全部的id映射,包括一些附带的数据
        for (int i=0;i<objIdArray.length();i++)  
        {
            IdPair.setKey(objIdArray[i]);
            if (idMap.compute(IdPair))
            {
                arrID2.append(IdPair.value());
            }
        }
        if (!arrID2.isEmpty())
        {
            acutPrintf(_T("\n复制:%d个对象成功!"),arrID2.length());
        }
        
        //#define Randmod(x) rand()%x
        //亮显选择集
        ads_name ss,ent;
        acedSSAdd(NULL,NULL,ss);
        for (int i=0;i<arrID2.length();i++)
        {
            AcDbEntityPointer pEnt(arrID2[i],AcDb::kForWrite);
            if (Acad::eOk == pEnt.openStatus())
            {
                //pEnt->setColorIndex(Randmod(11));
                acdbGetAdsName(ent,arrID2[i]);
                acedSSAdd(ent,ss,ss);
//                 if (pEnt->isKindOf(AcDbDimension::desc()))
//                 {
//                     AcDbDimension *pDim=AcDbDimension::cast(pEnt);
//                     pDim->recomputeDimBlock();
//                 }
                pEnt->recordGraphicsModified();
                pEnt->close();
            }                    
        }
        Adesk::Int32 nLength;
        acedSSLength(ss,&nLength);        
        if (nLength>0)
        {
            acedSSSetFirst(ss,NULL);
        }
        //acedCommand(RTSTR,_T("_.select"),RTPICKS,ss,RTSTR,_T(""),RTNONE);        
        acedSSFree(ss);

https://www.cnblogs.com/unicornsir/p/10621312.html

objectarx 读取外部DWG图到当前图形

void CTrimeDraw::MyReadDwgFile(CString str)
{

 AcDbDatabase pExternalDb(Adesk::kFalse);
 // 外部图形数据库
 if (Acad::eOk != pExternalDb.readDwgFile(str,_SH_DENYRW,false))
 {
  acedAlert(_T("读取DWG文件失败!"));
  return;
 }
 
 AcDbDatabase *pTempDb,*pData;
 if (Acad::eOk!=pExternalDb.wblock(pTempDb))
 {
  acedAlert(_T("wBlock操作失败"));
  return;
 }

 pData=acdbHostApplicationServices()->workingDatabase();
 if (Acad::eOk!=pData
  ->insert(AcGeMatrix3d::kIdentity,pTempDb))
 {
  acedAlert(_T("insert 操作失败!"));
 }
 delete pTempDb;
 acdbHostApplicationServices()->setWorkingDatabase(pData);
}

关于天正实体将CAD的复制、粘帖功能破坏探究


关于天正实体将CAD的复制、粘帖功能破坏探究

 

由于天正是中国建筑软件的龙头老大,目前大部分建筑图都由天正完成。而天正为了追求出图时,图纸容量不至过大,在自定义实体中不使用代理实体的方式。这样势必造成了一种问题,这就是在使用者的机器上必须有天正软件存在才能看到天正实体,否则不能看见和使用。天正为了解决这种问题,专门写了一个插件,此插件的功能是专门寻找天正实体,如果用户只是想出图而不想安装天正软件的话,只需要安装天正插就行了。这也是天正防盗版的一种措施:我天正的图,只有天正的东西才能使用,即使普通的打印功能也不提供给你!!!!!!

 

但是天正又没完全能解决好此问题:如果我的图中有天正实体,而又不想安装天正插件,天正就将CAD的复制、粘帖的功能都给毙掉了,究其原因是天正的实体自己处理的有问题。

 

基于以上原因,我们在使用CAD的二次开发工具的过程中,如果使用到了AcDbDatabase的WBlock和Insert函数时,由于图中有天正实体存在而此机器上又没安装天正插件,天正破坏了AcDbDatabase的WBlock和Insert功能,这样会导致我们使用时的错误。此时我们需要做一些特别的处理了:如果生成不成功的话,提示用户是否有其它的实体存在,比如天正的实体,提示他安装天正插件了。


复制图纸空间的视口到另一个dwg文件中2(wblockcloneobjects方法)

https://www.it610.com/article/1280182852633247744.htm

上一次说wblockcloneobjcts方法不能写视口,又研究了一下,把“曲线救国”方法发挥到极致,终于有点
收获了。试了N种方法,最后采用的是:先建立一个模板,把图纸空间初始化,然后wblockcloneobjects到模型
空间(wblock命令也是把对象放到模型空间的,如果wblockcloneobjcts直接放图纸空间,打开视口时cad会崩溃)。
然后再将视口deepclone到图纸空间就OK了

 AcDbDatabase *pDbMid=new AcDbDatabase;
 //建模板dwg文件,先切换到图纸空间,把全局视口建起来
 //每个图纸空间都有一个全局视口,视口下还挂了反应器
 //直接wblockcloneobjects一个new的database的话,会因为没有这个视口而搞得acad崩溃
 //如果想用new的database,要先把这个全局视口建立起来,现在还不知道怎么建难过
 pDbMid->readDwgFile(_T("c:\\template.dwg"));  //读取模板

 ads_name name;
 ads_point pnt;
 AcDbEntity * pEnt;
 int i;
 Acad::ErrorStatus es;
 
 acedEntSel(_T("选择一个视口\n"),name,pnt);
 
 AcDbObjectId objId,dicObj;
 acdbGetObjectId(objId,name);
 AcDbObjectIdArray arrID;
 arrID.append(objId);
 
 acedEntSel(_T("选择一个视口\n"),name,pnt);
 acdbGetObjectId(objId,name);
 arrID.append(objId);

 
 //将扩展字典改为硬拥有,否则写块出去后会丢失
 AcDbObjectId tempObjId;
    for (i=0;iextensionDictionary())
    != AcDbObjectId::kNull)
   {
    AcDbDictionary *pDict = NULL;
    acdbOpenObject(pDict, obj, AcDb::kForWrite);
    if (pDict) {
     pDict->setTreatElementsAsHard(Adesk::kTrue);
     pDict->close();
    }
   }
   pEnt->close();
  }
  
    }
    
 AcDbBlockTable *pBT;  
 AcDbObjectId MspaceID,PspaceID,blkObjId;
 pDbMid->getSymbolTable(pBT,AcDb::kForWrite);   
  pBT->getAt(ACDB_MODEL_SPACE,MspaceID);


  pBT->close();

  AcDbIdMapping idMap;
  idMap.setDestDb(pDbMid);
     
 es=pDbMid->wblockCloneObjects(arrID,MspaceID,idMap,AcDb::kDrcIgnore);
    

  AcDbIdPair IdPair;
 AcDbObjectId cloneObjId;

 AcDbIdMapping idMap2;
 AcDbObjectIdArray arrID2;  
 for (i=0;ideepCloneObjects( arrID2,PspaceID, idMap2 );  //deepclone视口对象到图纸空间
   
   for (i=0;i<arrid2.length();i++) 删除原有模型空间的视口对象="" {="" idpair.setkey(arrid2[i]);="" if="" (idmap2.compute(idpair))="" 将图纸空间的视口打开="" acdbobjectpointerEntPtr1(IdPair.value(),AcDb::kForWrite);
     EntPtr1->setOn();
     EntPtr1->close();
    }
    
    AcDbObjectPointerEntPtr2(arrID2[i],AcDb::kForWrite);
    EntPtr2->erase();
    EntPtr2->close();

   }

    pBT->close();
    
 pDbMid->saveAs(_T("c:\\dddddd.dwg"));

 delete pDbMid;

复制图纸空间的视口到另一个dwg文件中

复制图纸空间的视口到另一个dwg文件中,wblockcloneobjects对无法复制视口,原因还不清楚,只能用wblock,思想是将选定的视口wblock做块到一个中间database,然后再将块插入目的database的图纸空间,最后炸开即可

AcDbDatabase *pDbMid=new AcDbDatabase;

ads_name name;

ads_point pnt;

AcDbEntity * pEnt;

int i;

Acad::ErrorStatus es;

acedEntSel(_T("选择一个视口\n"),name,pnt);

AcDbObjectId objId,dicObj;

acdbGetObjectId(objId,name);

AcDbObjectIdArray arrID;

arrID.append(objId);

acedEntSel(_T("选择一个视口\n"),name,pnt);

acdbGetObjectId(objId,name);

arrID.append(objId);

//将扩展字典改为硬拥有,否则写块出去后会丢失

AcDbObjectId tempObjId;

for (i=0;i<arrID.length();i++)

{

if(Acad::eOk==(es=acdbOpenObject(pEnt,arrID[i],AcDb::kForWrite))){

AcDbObjectId obj;

if ((obj = pEnt->extensionDictionary())

!= AcDbObjectId::kNull)

{

AcDbDictionary *pDict = NULL;

acdbOpenObject(pDict, obj, AcDb::kForWrite);

if (pDict) {

pDict->setTreatElementsAsHard(Adesk::kTrue);

pDict->close();

}

}

pEnt->close();

}

}

AcGePoint3d base(0,0,0);

acdbHostApplicationServices()->workingDatabase()->wblock(pDbMid,arrID,base);

AcDbDatabase *pDbDest=new AcDbDatabase;

AcDbObjectId blkId;

es= pDbDest->insert(blkId,_T("dddddddd"),pDbMid); //块名要起一个唯一的,按guid可以

AcDbBlockReference *pBlkR=new AcDbBlockReference;

AcDbBlockTable *pBT;

pDbDest->getSymbolTable(pBT,AcDb::kForWrite);

AcDbObjectId blkObjId,spaceID;

AcDbBlockTableRecord *pBpr;

pBT->getAt(_T("dddddddd"),blkObjId);

pBT->getAt(ACDB_PAPER_SPACE,pBpr,AcDb::kForWrite);

pBlkR->setBlockTableRecord(blkObjId); //设置块参照

AcDbVoidPtrArray pExplodeEntArr;

pBlkR->explode(pExplodeEntArr); //炸开块

for (i=0;i<pExplodeEntArr.length();i++)

{

AcDbEntity * pEnt=(AcDbEntity*)pExplodeEntArr[i];

pBpr->appendAcDbEntity(pEnt);

pEnt->close();

}

pBlkR->erase();

pBlkR->close();

pBpr->close();

//插入完成后把块表删掉

pBT->getAt(_T("dddddddd"),pBpr,AcDb::kForWrite);

pBpr->erase();

pBpr->close();

pBT->close();

pDbDest->saveAs(_T("c:\\rrrrrrr.dwg"));

delete pBlkR;

delete pDbDest;

delete pDbMid;

如果需要,再把源database中的图纸空间和模型空间的其他非视口对象wblcokcloneobjects到目的database,就

完成整个带视口的dwg文件的复制了.



如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

标签云