oeuf 发表于 2004-10-12 16:34:00

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

请问关于arx读取文件的问题<BR>用AcDbDatabase pDb建一个临时数据库<BR>用它来读取dwg文件,<BR>pDb-&gt;readDwgFile(fileName);<BR>然后得到所需块的id





AcDbBlockTable *pBlockTable;<BR>pDb-&gt;getBlockTable(pBlockTable, AcDb::kForRead);


AcDbBlockTableRecord *pBlockTableRecord;<BR>pBlockTable-&gt;getAt(blockName,blockId);//blockName已知<BR>pBlockTable-&gt;close();


<BR>这样得到blockId后如何将这个块插入到当前数据库并显示?<BR>谢谢!<BR>

pengst 发表于 2004-10-13 23:15:00

基本概念错误

想的太简单了


从一个文件中的块定义Id不能直接拿到另一个文件中作为块参照Id用的,给你一个函数参考


它将外部DWG文件中的块定义复制到当前文件中作为块定义,之后用这个块在当前文件中的块定义Id并插入


//将外部DWG中的块定义导入到当前图形中<BR>//如果当前有同名块定义,则无论是否被参照都将被覆盖,同时参照实体更新<BR>Acad::ErrorStatus ImportBlockDefineFromDwg(CString strSourceDwgFile,CString strBlockName,CString strNewBlockName)<BR>{<BR>        AcDbDatabase* pSourceDb;<BR>        Acad::ErrorStatus es;


        //打开外部文件<BR>        pSourceDb=new AcDbDatabase(Adesk::kFalse);<BR>        es=pSourceDb-&gt;readDwgFile(strSourceDwgFile);<BR>        if (es!=Acad::eOk) {<BR>                //ads_printf("Error readDwgFile %d",es);<BR>                delete pSourceDb;<BR>                return es;<BR>        }<BR>        <BR>        //获取源文件中的块表<BR>        AcDbBlockTable *pBlockTable;<BR>#ifdef ACADR14<BR>        es=pSourceDb-&gt;getBlockTable(pBlockTable,AcDb::kForRead);<BR>#else<BR>        es=pSourceDb-&gt;getSymbolTable(pBlockTable,AcDb::kForRead);<BR>#endif<BR>        if (es!=Acad::eOk) {<BR>                //ads_printf("Error getSymBolTable %d",es);<BR>                delete pSourceDb;<BR>                return es;<BR>        }<BR>        <BR>        //寻找块strBlockName<BR>        AcDbBlockTableRecord * pBlockTableRecord;<BR>        es = pBlockTable-&gt;getAt(strBlockName,pBlockTableRecord,AcDb::kForRead);<BR>        if (es!=Acad::eOk) {<BR>                //源DWG中未找到块定义<BR>                delete pSourceDb;<BR>                pBlockTable-&gt;close();<BR>                return es;<BR>        }


        //插入到目标DWG中<BR>        AcDbObjectId eId;<BR>        AcGePoint3d ptBase;<BR>        AcDbObjectIdArray ayBlock,aySolids;<BR>        AcDbDatabase *pBlockDatabase;<BR>        AcDbEntity *pEnt;<BR>        <BR>        ptBase.set(0,0,0);


        //遍历源DWG中组成块定义的实体,并添加到实体表ayBlock中<BR>        AcDbBlockTableRecordIterator *pBlkIter;<BR>        pBlockTableRecord-&gt;newIterator(pBlkIter);<BR>        for (pBlkIter-&gt;start();!pBlkIter-&gt;done();pBlkIter-&gt;step()) {                        <BR>                pBlkIter-&gt;getEntityId(eId);<BR>                if (acdbOpenObject(pEnt,eId,AcDb::kForRead)==Acad::eOk) {<BR>                        if (pEnt-&gt;isKindOf(AcDbSolid::desc()) ||<BR>                                pEnt-&gt;isKindOf(AcDb2dPolyline::desc()) ||<BR>                                pEnt-&gt;isKindOf(AcDbPolyline::desc()) ||<BR>                                pEnt-&gt;isKindOf(AcDbFace::desc()) ||<BR>                                pEnt-&gt;isKindOf(CommonPolyline::desc()) ||<BR>                                pEnt-&gt;isKindOf(CommonSolid::desc())<BR>                                )<BR>                        {<BR>                                aySolids.append(eId);<BR>                        }<BR>                        else {<BR>                                ayBlock.append(eId);<BR>                        }<BR>                        pEnt-&gt;close();<BR>                }<BR>        }<BR>        delete pBlkIter;<BR>        //将aySolids中底实体按大至小排序,先显示大图形<BR>        int i;<BR>        int iLen=aySolids.length();<BR>        if (iLen&gt;0) {<BR>                BOOL bExchange=TRUE;<BR>                double dArea;<BR>                AcDbExtents extEnt1,extEnt2;<BR>                AcGePoint3d ptExt;<BR>                AcDbObjectId eId1,eId2;<BR>                AcDbEntity *pEnt1,*pEnt2;


                while (bExchange==TRUE) {<BR>                        bExchange=FALSE;<BR>                        for (i=0;i&lt;iLen-1;i++) {<BR>                                eId1=aySolids;<BR>                                eId2=aySolids;<BR>                                if (acdbOpenObject(pEnt1,eId1,AcDb::kForRead)==Acad::eOk) {<BR>                                        if (acdbOpenObject(pEnt2,eId2,AcDb::kForRead)==Acad::eOk) {<BR>                                                if (pEnt1-&gt;getGeomExtents(extEnt1)==Acad::eOk) {<BR>                                                        if (pEnt2-&gt;getGeomExtents(extEnt2)==Acad::eOk) {<BR>                                                                ptExt=extEnt1.minPoint();<BR>                                                                ptExt=extEnt1.maxPoint();<BR>                                                                dArea=fabs((ptExt-ptExt)*(ptExt-ptExt));<BR>                                                                ptExt=extEnt2.minPoint();<BR>                                                                ptExt=extEnt2.maxPoint();<BR>                                                                dArea=fabs((ptExt-ptExt)*(ptExt-ptExt));<BR>                                                                if (dArea&lt;dArea) {<BR>                                                                        bExchange=TRUE;<BR>                                                                        aySolids=eId2;<BR>                                                                        aySolids=eId1;<BR>                                                                }<BR>                                                        }<BR>                                                }<BR>                                                pEnt2-&gt;close();<BR>                                        }<BR>                                        pEnt1-&gt;close();<BR>                                }<BR>                                if (bExchange==TRUE) {break;}<BR>                        }<BR>                }<BR>                for (i=0;i&lt;ayBlock.length();i++) {aySolids.append(ayBlock);}<BR>                ayBlock=aySolids;<BR>        }                <BR>        ///////////////////////////////////////////////////////////////////////////////////<BR>        pBlockTableRecord-&gt;close();<BR>        pBlockTable-&gt;close();


        //写新块数据到pBlockDatabase;<BR>        es=pSourceDb-&gt;wblock(pBlockDatabase,ayBlock,ptBase);<BR>        //ads_printf("\nwblock=%d",es);


        AcDbObjectId eNewBlockId;<BR>        //将数据pBlockDatabase读入到目标DWG中,新块定义eNewBlockId;<BR>        es = CurrectWorkingDWG-&gt;insert(eNewBlockId, strNewBlockName, pBlockDatabase, Adesk::kTrue);<BR>        //ads_printf("\nInsert=%d",es);<BR>        delete pBlockDatabase;<BR>                <BR>        delete pSourceDb;<BR>        <BR>        return es;<BR>}

oeuf 发表于 2004-10-14 14:17:00

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

我以前的做法是用一个临时数据库读取dwg文件,然后insert到当前数据库


但是这样的做就会把所有的块都先插入到当前数据库后,再选择自己想要的


如果我原来的那个dwg定义了10个block,而我只要插入一个的话,那就很不合理了,因为这10个都已经放到当前数据库了,并且还有一个newId,很浪费


不知道这个怎么解决???


        AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);<BR>                       if (Acad::eOk != pDb-&gt;readDwgFile(path))<BR>                       {<BR>                                                       acedAlert( "Error reading DWG!" );<BR>                                                       return;<BR>                       }


        AcDbObjectId newId;<BR>        acdbHostApplicationServices()-&gt;workingDatabase()-&gt;insert(newId,"newBlock",pDb);<BR>        delete pDb;


        AcDbBlockTable *pBlockTable;<BR>        acdbHostApplicationServices()-&gt;workingDatabase()-&gt;getSymbolTable(pBlockTable,AcDb::kForRead);<BR>        AcDbObjectId blockId;<BR>        pBlockTable-&gt;getAt(blockName,blockId);


        AcDbBlockReference *pBlkRef=new AcDbBlockReference();<BR>        pBlkRef-&gt;setBlockTableRecord(blockId);<BR><BR>        AcDbBlockTableRecord *pBlockTableRecord;<BR>        pBlockTable-&gt;getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);<BR>        pBlockTable-&gt;close();


        pBlockTableRecord-&gt;appendAcDbEntity(pBlkRef);<BR>        pBlockTableRecord-&gt;close();<BR>        pBlkRef-&gt;close();


后来我又找到doc里面有个sample,是讲clone的,它的做法也是用一个临时的Database读取,然后遍历到另一个database里,然后Insert到当前数据库


但是我把其中一个小地方改了一下就不行了,郁闷


它的源码是这样:


        AcDbObjectId id;<BR>                       AcDbObjectIdArray list;<BR>                       AcDbDatabase extDatabase( Adesk::kFalse );


                       if (Acad::eOk != extDatabase.readDwgFile(path))<BR>                       {<BR>                                                       acedAlert( "Error reading DWG!" );<BR>                                                       return;<BR>                       }<BR>                       AcDbBlockTable* pBT;<BR>                       if (Acad::eOk != extDatabase.getSymbolTable( pBT, AcDb::kForRead ))<BR>                       {<BR>                                                       acedAlert( "Error getting BlockTable of DWG" );<BR>                                                       return;<BR>                       }


        AcDbBlockTableRecord* pBTR;<BR>        Acad::ErrorStatus es = pBT-&gt;getAt( ACDB_MODEL_SPACE, pBTR, AcDb::kForRead );<BR>        pBT-&gt;close();<BR>        if (Acad::eOk != es) {<BR>                                                       acedAlert( "Error getting model space of DWG" );<BR>                                                       return;<BR>                       }


<BR>                       AcDbBlockTableRecordIterator* pIT;<BR>                       if (Acad::eOk != pBTR-&gt;newIterator( pIT )) {<BR>                                                       acedAlert( "Error iterating model space of DWG" );<BR>                                                       pBTR-&gt;close();<BR>                                                       return;<BR>                       }


<BR>                       for ( ; !pIT-&gt;done(); pIT-&gt;step()) {<BR>                                                       if (Acad::eOk == pIT-&gt;getEntityId( id )) {<BR>                        acutPrintf(" %lx",id);<BR>                                                                                       list.append( id );


                                                                                       AcDbEntity *pEnt;<BR>                                                                                       if ( Acad::eOk == pIT-&gt;getEntity(pEnt, AcDb::kForRead)) {<BR>                                                                                                                       AcDbObjectId obj;<BR>                                                                                                                       if ((obj = pEnt-&gt;extensionDictionary())<BR>                                                                                                                                                       != AcDbObjectId::kNull)<BR>                                                                                                                       {<BR>                                                                                                                                                       AcDbDictionary *pDict = NULL;<BR>                                                                                                                                                       acdbOpenObject(pDict, obj, AcDb::kForWrite);<BR>                                                                                                                                                       if (pDict) {<BR>                                                                                                                                                                                       pDict-&gt;setTreatElementsAsHard(Adesk::kTrue);<BR>                                                                                                                                                                                       pDict-&gt;close();<BR>                                                                                                                                                       }<BR>                                                                                                                       }<BR>                                                                                                                       pEnt-&gt;close();<BR>                                                                                       }<BR>                                                       }<BR>                       }<BR>                       delete pIT;


        pBTR-&gt;close();


                       if (list.isEmpty()) {<BR>                                                       acedAlert( "No entities found in model space of DWG" );<BR>                                                       return;<BR>                       }


                       AcDbDatabase *pTempDb;


                       if (Acad::eOk != extDatabase.wblock( pTempDb, list, AcGePoint3d::kOrigin ))<BR>                       {<BR>                                                       acedAlert( "wblock failed!" );<BR>                                                       return;<BR>                       }<BR>                       if (Acad::eOk != acdbHostApplicationServices()-&gt;workingDatabase()<BR>                                                       -&gt;insert( AcGeMatrix3d::kIdentity, pTempDb ))<BR>                                                       acedAlert( "insert failed!" );


                       delete pTempDb;<BR>


它是遍历每个实体,而我只想要我自己想要的


所以我改成了这样


        AcDbObjectId id;<BR>                       AcDbObjectIdArray list;<BR>                       AcDbDatabase extDatabase( Adesk::kFalse );


                       if (Acad::eOk != extDatabase.readDwgFile(path))<BR>                       {<BR>                                                       acedAlert( "Error reading DWG!" );<BR>                                                       return;<BR>                       }<BR>                       AcDbBlockTable* pBT;<BR>                       if (Acad::eOk != extDatabase.getSymbolTable( pBT, AcDb::kForRead ))<BR>                       {<BR>                                                       acedAlert( "Error getting BlockTable of DWG" );<BR>                                                       return;<BR>                       }


        pBT-&gt;getAt(blockName,id);               //修改的地方<BR>        acutPrintf(" %lx",id);                                                                                                       //修改的地方<BR>        list.append( id );                                                                                                                                               //修改的地方


                       if (list.isEmpty()) {<BR>                                                       acedAlert( "No entities found in model space of DWG" );<BR>                                                       return;<BR>                       }


                       AcDbDatabase *pTempDb;


                       if (Acad::eOk != extDatabase.wblock( pTempDb, list, AcGePoint3d::kOrigin ))<BR>                       {<BR>                                                       acedAlert( "wblock failed!" );<BR>                                                       return;<BR>                       }<BR>                       if (Acad::eOk != acdbHostApplicationServices()-&gt;workingDatabase()<BR>                                                       -&gt;insert( AcGeMatrix3d::kIdentity, pTempDb ))<BR>                                                       acedAlert( "insert failed!" );


                       delete pTempDb;


这样就不行了


提示就是wblock failed!


这又是什么原因呢?照理说应该行的啊?
页: [1]
查看完整版本: arx读取dwg文件并选择块插入当前数据库的问题