wblockcloneobjcts

作者: admin 分类: CAD,ObjectARX 发布时间: 2019-11-27 20:23

上一次说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;

将当前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;

————————————————

ObjectARX学习笔记(二十五)—如何在两个dwg里面拷贝字体样式表AcGiTextStyle ,AcDbTextStyleTableRecord

//两个dwg拷贝字体信息
bool CopyTextStyleIdInfo(AcDbDatabase *pFromDataSrc/*in*/,AcDbDatabase *pToDataDes/*in*/)
{
if (pFromDataSrc == NULL || pToDataDes == NULL)
return false;
 
AcDbTextStyleTable *pStyleTable = NULL;
Acad::ErrorStatus es = Acad::eOk;
es = pFromDataSrc->getSymbolTable(pStyleTable,AcDb::kForRead);
if (es != Acad::eOk)
return false;
 
AcDbTextStyleTableIterator *pIterator = NULL;
es = pStyleTable->newIterator(pIterator);
if (es != Acad::eOk)
{
pStyleTable->close();
pStyleTable = NULL;
return false;
}
 
for (pIterator->start();!pIterator->done();pIterator->step())
{
AcDbObjectId styleId = AcDbObjectId::kNull;
if ((es = pIterator->getRecordId(styleId)) == Acad::eOk)
{
AcGiTextStyle *pTextStyle=new AcGiTextStyle(pToDataDes);
if((es =fromAcDbTextStyle(*pTextStyle,styleId)) == Acad::eOk )
{
AcDbTextStyleTableRecord* pNewRec = new AcDbTextStyleTableRecord;
 
setSymbolName(pNewRec,pTextStyle->styleName());
pNewRec->setFileName(pTextStyle->fileName());
/*待完善*/ 
ACHAR * pTypeface = NULL;
Adesk::Boolean bold;
Adesk::Boolean italic;
int charset;
int pitchAndFamily;
es = pTextStyle->font(pTypeface,bold,italic,charset,pitchAndFamily);
if (es == Acad::eOk)
pNewRec->setFont(pTypeface,bold,italic,charset,pitchAndFamily);
 
pNewRec->setBigFontFileName(_T(""));// must explicitly set to ""
pNewRec->setTextSize(pTextStyle->textSize());
pNewRec->setObliquingAngle(pTextStyle->obliquingAngle());
pNewRec->setXScale(pTextStyle->xScale());
addToSymbolTableAndClose(pNewRec,pToDataDes);
}
if (pTextStyle != NULL)
{
delete pTextStyle;
pTextStyle = NULL;
}
}
}
 
if (pIterator != NULL)
{
delete pIterator;
pIterator = NULL;
pStyleTable->close();
pStyleTable = NULL;
}
return true;
}
if (pDataBase == NULL || systemTextRec == NULL)
    return FALSE;
 
AcDbTextStyleTable* symTextTbl = NULL;
 Acad::ErrorStatus es = Acad::eOk;
es = pDataBase->getTextStyleTable(symTextTbl, AcDb::kForWrite);
if (es != Acad::eOk)
{
if (systemTextRec != NULL)
{
delete systemTextRec;
systemTextRec = NULL;
}
return FALSE;
}
AcDbSymbolTable *pSysRec = AcDbTextStyleTable::cast(symTextTbl);
 //覆盖字体样式
 es = pSysRec->add(systemTextRec); 
 if (es != Acad::eOk )
 {
 symTextTbl->close(); 
 systemTextRec->close();
 return FALSE;
 }
 else
 {
systemTextRec->close();
    symTextTbl->close();
 }
return TRUE;
}
 
BOOL setSymbolName(AcDbSymbolTableRecord* newRec, LPCTSTR newName)
{
Acad::ErrorStatus es;
es = newRec->setName(newName);
if (es != Acad::eOk) {
newRec->close();
}
return(es);
}
 
//返回实体所在图层颜色 
Adesk::UInt16 getColorIndexByLayer(Adesk::UInt16 icolorIndex,CString lyname,AcDbDatabase *pDb)
{
if (pDb == NULL)
   return 7;
 
Adesk::UInt16 iclorIndexResult = 0;
Acad::ErrorStatus  bEs = Acad::eOk;
if (icolorIndex == 256) //随层
{
AcDbLayerTable *pDbLy;
bEs = pDb->getLayerTable(pDbLy,AcDb::kForRead);
if (bEs == Acad::eOk)
{
Adesk::Boolean es=pDbLy->has(lyname); 
if (es)
{
AcDbLayerTableRecord *pLayerTblRcd;
bEs = pDbLy->getAt(lyname,(AcDbLayerTableRecord*&)pLayerTblRcd, AcDb::kForRead);
if (bEs == Acad::eOk)
{
AcCmColor color = pLayerTblRcd->color();
iclorIndexResult = color.colorIndex();
pLayerTblRcd->close();
}
}
pDbLy->close();
}
}
else if(icolorIndex == 0) //随块
{
;//待完善
}
else
{
iclorIndexResult = icolorIndex;
}
return iclorIndexResult;
}
 
//添加文字样式块表记录
BOOL addToSymbolTableAndClose(AcDbSymbolTableRecord* systemTextRec/*in*/,AcDbDatabase *pDataBase/*in*/)
{
if (pDataBase == NULL || systemTextRec == NULL)
    return FALSE;
 
AcDbTextStyleTable* symTextTbl = NULL;
 Acad::ErrorStatus es = Acad::eOk;
es = pDataBase->getTextStyleTable(symTextTbl, AcDb::kForWrite);
if (es != Acad::eOk)
{
if (systemTextRec != NULL)
{
delete systemTextRec;
systemTextRec = NULL;
}
return FALSE;
}
AcDbSymbolTable *pSysRec = AcDbTextStyleTable::cast(symTextTbl);
 //覆盖字体样式
 es = pSysRec->add(systemTextRec); 
 if (es != Acad::eOk )
 {
 symTextTbl->close(); 
 systemTextRec->close();
 return FALSE;
 }
 else
 {
systemTextRec->close();
    symTextTbl->close();
 }
return TRUE;
}
 
BOOL setSymbolName(AcDbSymbolTableRecord* newRec, LPCTSTR newName)
{
Acad::ErrorStatus es;
es = newRec->setName(newName);
if (es != Acad::eOk) {
newRec->close();
}
return(es);
}
 
//返回实体所在图层颜色 
Adesk::UInt16 getColorIndexByLayer(Adesk::UInt16 icolorIndex,CString lyname,AcDbDatabase *pDb)
{
if (pDb == NULL)
   return 7;
 
Adesk::UInt16 iclorIndexResult = 0;
Acad::ErrorStatus  bEs = Acad::eOk;
if (icolorIndex == 256) //随层
{
AcDbLayerTable *pDbLy;
bEs = pDb->getLayerTable(pDbLy,AcDb::kForRead);
if (bEs == Acad::eOk)
{
Adesk::Boolean es=pDbLy->has(lyname); 
if (es)
{
AcDbLayerTableRecord *pLayerTblRcd;
bEs = pDbLy->getAt(lyname,(AcDbLayerTableRecord*&)pLayerTblRcd, AcDb::kForRead);
if (bEs == Acad::eOk)
{
AcCmColor color = pLayerTblRcd->color();
iclorIndexResult = color.colorIndex();
pLayerTblRcd->close();
}
}
pDbLy->close();
}
}
else if(icolorIndex == 0) //随块
{
;//待完善
}
else
{
iclorIndexResult = icolorIndex;
}
return iclorIndexResult;
}

[ObjectARX]-在图形数据库之间传递数据 Wblock

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/qq_40416052/article/details/82933824

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

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

实现代码:

AcDbObjectId CBlockUtil::CopyBlockDefFromOtherDwg(const TCHAR* fileName,

const TCHAR* blkDefName)

{

AcDbObjectId blockRefId = AcDbObjectId::kNull;

                        //AcDbObjectId :: kNull表示当前DWG中不存在对象(图层)

 

//使用_SH_DENYNO参数打开图形(只读打开),允许其他用户读写文件

AcDbDatabase* pSourceDwg = new AcDbDatabase(false);

Acad::ErrorStatus es = pSourceDwg->readDwgFile(fileName,

static_cast<AcDbDatabase::OpenMode>(_SH_DENYNO));

if (es != Acad::eOk)

{

delete pSourceDwg;

pSourceDwg = NULL;

 

acutPrintf(TEXT("\n读入dwg图形错误,图形名称:%s"), fileName);

return blockRefId;

}

 

//打开外部图形数据库的块表,寻找给定名称的块表记录

AcDbBlockTable* pBlkTable = NULL;

es = pSourceDwg->getBlockTable(pBlkTable, AcDb::kForRead);

                 //以只读模式打开数据库的块表,pBlkTable获得块表地址

assert(es == Acad::eOk);

bool bRet = false;

 

if (pBlkTable->has(blkDefName))  //不存在指定的图块

{

AcDbObjectId destBlkDefId; //指定图块的块表记录Id

es = pBlkTable->getAt(blkDefName, destBlkDefId);

 

//把指定的图块输出到一个临时的图形数据库

AcDbDatabase *pTempDb = NULL;  //注意:这里千万不能new

es = pSourceDwg->wblock(pTempDb, destBlkDefId);//创建一个新的数据库对象,pTempDb指向它

assert(es == Acad::eOk);

 

//把临时图形数据库作为插入块插入到当前dwg

AcDbDatabase* pCurDb = acdbHostApplicationServices()->workingDatabase();

es = pCurDb->insert(blockRefId, blkDefName, pTempDb);//由pDb指向的数据库中的所有

            //模型空间实体都被复制到新的块表记录中,新的块表记录名称为blkDefName,Id为blockRefId

assert(es == Acad::eOk);

delete pTempDb;

pTempDb = NULL;

}

else

{

acutPrintf(TEXT("\n给定的DWG文件中,不存在指定名称的块表记录."));

}

pBlkTable->close();

 

delete pSourceDwg;

pSourceDwg = NULL;

 

return blockRefId;

}

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

实现代码:

InsertDwgBlockDef函数的声明:

// 将DWG文件作为块定义加入到指定的图形数据库

// bOverwriteIfExist: 如果指定的图形数据库中已经定义了同名的块,是否覆盖原有的定义

static AcDbObjectId InsertDwgBlockDef(const TCHAR* dwgFileName, 

              const TCHAR* blkName, bool bOverwriteIfExist, 

      AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());

InsertDwgBlockDef函数的实现:

   AcDbObjectId CBlockUtil::InsertDwgBlockDef(const TCHAR* dwgFileName,

const TCHAR* blkName, bool bOverwriteIfExist, AcDbDatabase *pDb)

{

//是否包含指定名称的块定义

AcDbObjectId blkDefId = GetBlkDefId(blkName, pDb);

if (blkDefId.isNull() || bOverwriteIfExist)

{

if (_taccess(dwgFileName, 0) != -1)//如果指定的文件不存在,返回-1

{

AcDbDatabase *pBlkDb = new AcDbDatabase(false);

Acad::ErrorStatus es = pBlkDb->readDwgFile(dwgFileName, 

              static_cast<AcDbDatabase::OpenMode>(_SH_DENYNO));

if (es == Acad::eOk)

{

es = pDb->insert(blkDefId, blkName, pBlkDb);//在执行此insert函数的数据库中

              //创建新的块表记录;由pBlkDb指向的数据库中的所有模型空间实体都

              //被复制到新的块表记录中,名称为blkName,Id为blkDefId

if (es != Acad::eOk)

{

CString strMsg;

strMsg.Format(TEXT("CBlockUtil::InsertDwgBlockDef函数,insert失败:%d."),

(int)es);

AfxMessageBox(strMsg);

}

}

else

{

CString strMsg;

strMsg.Format(TEXT("CBlockUtil::InsertDwgBlockDef函数,readDwg File失败:%d."), 

(int)es);

AfxMessageBox(strMsg);

}

delete pBlkDb;

}

else

{

AfxMessageBox(TEXT("CBlockUtil::InsertDwgBlockDef函数,未找到指定的图块文件."));

}

}

return blkDefId;

}

其中,

GetBlkDefId函数的声明:

// 获得指定名称的块定义

static AcDbObjectId GetBlkDefId(const TCHAR* blkDefName,

 AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());

GetBlkDefId函数的实现:

// 获得指定名称的块定义

AcDbObjectId CBlockUtil::GetBlkDefId(const TCHAR* blkDefName, AcDbDatabase *pDb)

{

AcDbBlockTable* pBlockTable = NULL;

Acad::ErrorStatus es = pDb->getBlockTable(pBlockTable, AcDb::kForRead);

AcDbObjectId blkDefId;

es = pBlockTable->getAt(blkDefName, blkDefId);

pBlockTable->close();

 

if (es == Acad::eOk)

{

return blkDefId;

}

else

{

return AcDbObjectId::kNull;

}

}

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

注册函数InsertBlkRefFromOtherDwg的实现代码:

static void AAAMyGroupInsertBlkRefFromOtherDwg() {

CString fileName = TEXT("C:\\'包含图块.dwg");

if (_taccess(fileName, 0) != -1)

{

AcDbObjectId blkDefId = CBlockUtil::CopyBlockDefFromOtherDwg(fileName, 

TEXT("测试图块"));

if (blkDefId.isValid())

{

CBlockUtil::InsertBlockRef(blkDefId, AcGePoint3d(100, 100, 0), 1, 0);

}

}

else

{

acutPrintf(TEXT("\n指定的图形文件不存在"));

}

 

}

其中,

InsertBlockRef函数的声明:

// 插入块参照

static AcDbObjectId InsertBlockRef(AcDbObjectId blkDefId, const AcGePoint3d &insertPoint,

 double scale = 1, double rotation = 0);

InsertBlockRef函数的实现:

// 插入块参照

AcDbObjectId CBlockUtil::InsertBlockRef(AcDbObjectId blkDefId, const AcGePoint3d &insertPoint, double scale,

double rotation)

{

// 设置图块的插入点、旋转角度、比例等等

AcDbBlockReference *pBlkRef = new AcDbBlockReference(insertPoint, blkDefId);

pBlkRef->setRotation(rotation);

SetScaleFactor(pBlkRef, scale);

 

// 把新建的图块参照实体加入到新建的块表记录中,并取得插入图块的实体Id,用于返回值

return CDwgDatabaseUtil::PostToModelSpace(pBlkRef);

}

② 

SetScaleFactor函数的声明: 

 

// 设置块参照的缩放比例

static void SetScaleFactor(AcDbBlockReference *pBlkRef, double scale);

SetScaleFactor函数的实现:  

// 修改块参照的插入比例

void CBlockUtil::SetScaleFactor( AcDbBlockReference *pBlkRef, double scale )

{

assert (pBlkRef);

AcGeScale3d geScale(scale, scale, scale);

pBlkRef->setScaleFactors(geScale);

}

③ 

PostToModelSpace函数的声明:

// 将实体添加到模型空间

static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt, 

     AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());

PostToModelSpace函数的声明: 

 

AcDbObjectId CDwgDatabaseUtil::PostToModelSpace(AcDbEntity *pEnt, AcDbDatabase *pDb)

{

// 检查输入参数的有效性

assert(pEnt); // 等效于assert (pEnt != NULL);

 

// 获得当前图形数据库的块表

AcDbBlockTable *pBlkTbl = NULL;

pDb->getBlockTable(pBlkTbl, AcDb::kForRead);

 

// 获得模型空间对应的块表记录

AcDbBlockTableRecord *pBlkTblRcd = NULL;

pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd, AcDb::kForWrite);

pBlkTbl->close();

 

// 将实体添加到模型空间的块表记录

AcDbObjectId entId;

Acad::ErrorStatus es = pBlkTblRcd->appendAcDbEntity(entId, pEnt);

if (es != Acad::eOk)

{

pBlkTblRcd->close();

delete pEnt; // 添加失败时,要delete

pEnt = NULL;

 

return AcDbObjectId::kNull;

}

 

// 关闭模型空间块表记录和实体

pBlkTblRcd->close();

pEnt->close();

 

return entId;

}

 

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

实现代码为:

注册函数InsertDwgBlockRef 的实现:

static void AAAMyGroupInsertDwgBlockRef() {

CString fileName = TEXT("C:\\作为图块的文件.dwg");

if (_taccess(fileName, 0) != -1)

{

AcDbObjectId blkDefId = CBlockUtil::InsertDwgBlockDef(fileName,

TEXT("外部DWG图块"), true);

if (blkDefId.isValid())

{

CBlockUtil::InsertBlockRef(blkDefId, AcGePoint3d(200, 100, 0), 1, 0);

}

}

else

{

acutPrintf(TEXT("\n指定的图形文件不存在."));

}

 

}

思路总结: 

————————————————

版权声明:本文为CSDN博主「李燕良」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_40416052/article/details/82933824

20181005171921613.jpg

Wblock.rar

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

发表评论

标签云