乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 41|回复: 2

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

[复制链接]

2

主题

4

帖子

2

银币

初来乍到

Rank: 1

铜币
12
发表于 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后如何将这个块插入到当前数据库并显示?
谢谢!
回复

使用道具 举报

0

主题

10

帖子

3

银币

初来乍到

Rank: 1

铜币
10
发表于 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[i];
                                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]close();
                                        }
                                        pEnt1->close();
                                }
                                if (bExchange==TRUE) {break;}
                        }
                }
                for (i=0;iclose();
        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;
}
回复

使用道具 举报

2

主题

4

帖子

2

银币

初来乍到

Rank: 1

铜币
12
发表于 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!
这又是什么原因呢?照理说应该行的啊?
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-4 23:54 , Processed in 0.218872 second(s), 58 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表