上一次说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;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(); } } 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;i<arrID.length();i++) //获取克隆后的对象的objectid { IdPair.setKey(arrID[i]); if (idMap.compute(IdPair)) { arrID2.append(IdPair.value()); } } AcDbSymbolUtilities::getBlockId(PspaceID,ACDB_PAPER_SPACE,pDbMid); es=pDbMid->deepCloneObjects( arrID2,PspaceID, idMap2 ); //deepclone视口对象到图纸空间 for (i=0;i<arrID2.length();i++) //删除原有模型空间的视口对象 { IdPair.setKey(arrID2[i]); if (idMap2.compute(IdPair)) //将图纸空间的视口打开 { AcDbObjectPointer<AcDbViewport> EntPtr1(IdPair.value(),AcDb::kForWrite); EntPtr1->setOn(); EntPtr1->close(); } AcDbObjectPointer<AcDbViewport> EntPtr2(arrID2[i],AcDb::kForWrite); EntPtr2->erase(); EntPtr2->close(); } pBT->close(); pDbMid->saveAs(_T("c:\\dddddd.dwg")); delete pDbMid;