将当前dwg内的对象复制到另一个dwg文件中
//将当前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文件的复制了.