明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3636|回复: 2

arx读取dwg文件并选择块插入当前数据库的问题

[复制链接]
发表于 2004-10-12 16:34:00 | 显示全部楼层 |阅读模式
请问关于arx读取文件的问题
用AcDbDatabase pDb建一个临时数据库
用它来读取dwg文件,
pDb->readDwgFile(fileName);
然后得到所需块的id AcDbBlockTable *pBlockTable;
pDb->getBlockTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(blockName,blockId);//blockName已知
pBlockTable->close();
这样得到blockId后如何将这个块插入到当前数据库并显示?
谢谢!
发表于 2004-10-13 23:15:00 | 显示全部楼层

基本概念错误

想的太简单了 从一个文件中的块定义Id不能直接拿到另一个文件中作为块参照Id用的,给你一个函数参考 它将外部DWG文件中的块定义复制到当前文件中作为块定义,之后用这个块在当前文件中的块定义Id并插入 //将外部DWG中的块定义导入到当前图形中
//如果当前有同名块定义,则无论是否被参照都将被覆盖,同时参照实体更新
Acad::ErrorStatus ImportBlockDefineFromDwg(CString strSourceDwgFile,CString strBlockName,CString strNewBlockName)
{
AcDbDatabase* pSourceDb;
Acad::ErrorStatus es; //打开外部文件
pSourceDb=new AcDbDatabase(Adesk::kFalse);
es=pSourceDb->readDwgFile(strSourceDwgFile);
if (es!=Acad::eOk) {
//ads_printf("Error readDwgFile %d",es);
delete pSourceDb;
return es;
}

//获取源文件中的块表
AcDbBlockTable *pBlockTable;
#ifdef ACADR14
es=pSourceDb->getBlockTable(pBlockTable,AcDb::kForRead);
#else
es=pSourceDb->getSymbolTable(pBlockTable,AcDb::kForRead);
#endif
if (es!=Acad::eOk) {
//ads_printf("Error getSymBolTable %d",es);
delete pSourceDb;
return es;
}

//寻找块strBlockName
AcDbBlockTableRecord * pBlockTableRecord;
es = pBlockTable->getAt(strBlockName,pBlockTableRecord,AcDb::kForRead);
if (es!=Acad::eOk) {
//源DWG中未找到块定义
delete pSourceDb;
pBlockTable->close();
return es;
} //插入到目标DWG中
AcDbObjectId eId;
AcGePoint3d ptBase;
AcDbObjectIdArray ayBlock,aySolids;
AcDbDatabase *pBlockDatabase;
AcDbEntity *pEnt;

ptBase.set(0,0,0); //遍历源DWG中组成块定义的实体,并添加到实体表ayBlock中
AcDbBlockTableRecordIterator *pBlkIter;
pBlockTableRecord->newIterator(pBlkIter);
for (pBlkIter->start();!pBlkIter->done();pBlkIter->step()) {
pBlkIter->getEntityId(eId);
if (acdbOpenObject(pEnt,eId,AcDb::kForRead)==Acad::eOk) {
if (pEnt->isKindOf(AcDbSolid::desc()) ||
pEnt->isKindOf(AcDb2dPolyline::desc()) ||
pEnt->isKindOf(AcDbPolyline::desc()) ||
pEnt->isKindOf(AcDbFace::desc()) ||
pEnt->isKindOf(CommonPolyline::desc()) ||
pEnt->isKindOf(CommonSolid::desc())
)
{
aySolids.append(eId);
}
else {
ayBlock.append(eId);
}
pEnt->close();
}
}
delete pBlkIter;
//将aySolids中底实体按大至小排序,先显示大图形
int i;
int iLen=aySolids.length();
if (iLen>0) {
BOOL bExchange=TRUE;
double dArea[2];
AcDbExtents extEnt1,extEnt2;
AcGePoint3d ptExt[2];
AcDbObjectId eId1,eId2;
AcDbEntity *pEnt1,*pEnt2; while (bExchange==TRUE) {
bExchange=FALSE;
for (i=0;i<iLen-1;i++) {
eId1=aySolids;
eId2=aySolids[i+1];
if (acdbOpenObject(pEnt1,eId1,AcDb::kForRead)==Acad::eOk) {
if (acdbOpenObject(pEnt2,eId2,AcDb::kForRead)==Acad::eOk) {
if (pEnt1->getGeomExtents(extEnt1)==Acad::eOk) {
if (pEnt2->getGeomExtents(extEnt2)==Acad::eOk) {
ptExt[0]=extEnt1.minPoint();
ptExt[1]=extEnt1.maxPoint();
dArea[0]=fabs((ptExt[1][X]-ptExt[0][X])*(ptExt[1][Y]-ptExt[0][Y]));
ptExt[0]=extEnt2.minPoint();
ptExt[1]=extEnt2.maxPoint();
dArea[1]=fabs((ptExt[1][X]-ptExt[0][X])*(ptExt[1][Y]-ptExt[0][Y]));
if (dArea[0]<dArea[1]) {
bExchange=TRUE;
aySolids=eId2;
aySolids[i+1]=eId1;
}
}
}
pEnt2->close();
}
pEnt1->close();
}
if (bExchange==TRUE) {break;}
}
}
for (i=0;i<ayBlock.length();i++) {aySolids.append(ayBlock);}
ayBlock=aySolids;
}
///////////////////////////////////////////////////////////////////////////////////
pBlockTableRecord->close();
pBlockTable->close(); //写新块数据到pBlockDatabase;
es=pSourceDb->wblock(pBlockDatabase,ayBlock,ptBase);
//ads_printf("\nwblock=%d",es); AcDbObjectId eNewBlockId;
//将数据pBlockDatabase读入到目标DWG中,新块定义eNewBlockId;
es = CurrectWorkingDWG->insert(eNewBlockId, strNewBlockName, pBlockDatabase, Adesk::kTrue);
//ads_printf("\nInsert=%d",es);
delete pBlockDatabase;

delete pSourceDb;

return es;
}
 楼主| 发表于 2004-10-14 14:17:00 | 显示全部楼层

谢谢回复!!!不过我还想问问??

我以前的做法是用一个临时数据库读取dwg文件,然后insert到当前数据库 但是这样的做就会把所有的块都先插入到当前数据库后,再选择自己想要的 如果我原来的那个dwg定义了10个block,而我只要插入一个的话,那就很不合理了,因为这10个都已经放到当前数据库了,并且还有一个newId,很浪费 不知道这个怎么解决??? AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);
if (Acad::eOk != pDb->readDwgFile(path))
{
acedAlert( "Error reading DWG!" );
return;
} AcDbObjectId newId;
acdbHostApplicationServices()->workingDatabase()->insert(newId,"newBlock",pDb);
delete pDb; AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable,AcDb::kForRead);
AcDbObjectId blockId;
pBlockTable->getAt(blockName,blockId); AcDbBlockReference *pBlkRef=new AcDbBlockReference();
pBlkRef->setBlockTableRecord(blockId);

AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);
pBlockTable->close(); pBlockTableRecord->appendAcDbEntity(pBlkRef);
pBlockTableRecord->close();
pBlkRef->close(); 后来我又找到doc里面有个sample,是讲clone的,它的做法也是用一个临时的Database读取,然后遍历到另一个database里,然后Insert到当前数据库 但是我把其中一个小地方改了一下就不行了,郁闷 它的源码是这样: AcDbObjectId id;
AcDbObjectIdArray list;
AcDbDatabase extDatabase( Adesk::kFalse ); if (Acad::eOk != extDatabase.readDwgFile(path))
{
acedAlert( "Error reading DWG!" );
return;
}
AcDbBlockTable* pBT;
if (Acad::eOk != extDatabase.getSymbolTable( pBT, AcDb::kForRead ))
{
acedAlert( "Error getting BlockTable of DWG" );
return;
} AcDbBlockTableRecord* pBTR;
Acad::ErrorStatus es = pBT->getAt( ACDB_MODEL_SPACE, pBTR, AcDb::kForRead );
pBT->close();
if (Acad::eOk != es) {
acedAlert( "Error getting model space of DWG" );
return;
}
AcDbBlockTableRecordIterator* pIT;
if (Acad::eOk != pBTR->newIterator( pIT )) {
acedAlert( "Error iterating model space of DWG" );
pBTR->close();
return;
}
for ( ; !pIT->done(); pIT->step()) {
if (Acad::eOk == pIT->getEntityId( id )) {
acutPrintf(" %lx",id);
list.append( id ); 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 pIT; pBTR->close(); if (list.isEmpty()) {
acedAlert( "No entities found in model space of DWG" );
return;
} AcDbDatabase *pTempDb; if (Acad::eOk != extDatabase.wblock( pTempDb, list, AcGePoint3d::kOrigin ))
{
acedAlert( "wblock failed!" );
return;
}
if (Acad::eOk != acdbHostApplicationServices()->workingDatabase()
->insert( AcGeMatrix3d::kIdentity, pTempDb ))
acedAlert( "insert failed!" ); delete pTempDb;
它是遍历每个实体,而我只想要我自己想要的 所以我改成了这样 AcDbObjectId id;
AcDbObjectIdArray list;
AcDbDatabase extDatabase( Adesk::kFalse ); if (Acad::eOk != extDatabase.readDwgFile(path))
{
acedAlert( "Error reading DWG!" );
return;
}
AcDbBlockTable* pBT;
if (Acad::eOk != extDatabase.getSymbolTable( pBT, AcDb::kForRead ))
{
acedAlert( "Error getting BlockTable of DWG" );
return;
} pBT->getAt(blockName,id); //修改的地方
acutPrintf(" %lx",id); //修改的地方
list.append( id ); //修改的地方 if (list.isEmpty()) {
acedAlert( "No entities found in model space of DWG" );
return;
} AcDbDatabase *pTempDb; if (Acad::eOk != extDatabase.wblock( pTempDb, list, AcGePoint3d::kOrigin ))
{
acedAlert( "wblock failed!" );
return;
}
if (Acad::eOk != acdbHostApplicationServices()->workingDatabase()
->insert( AcGeMatrix3d::kIdentity, pTempDb ))
acedAlert( "insert failed!" ); delete pTempDb; 这样就不行了 提示就是wblock failed! 这又是什么原因呢?照理说应该行的啊?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-26 10:28 , Processed in 0.167816 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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