June 2, 2013

Loại bỏ toàn bộ thực thể Proxy trong bản vẽ bằng ObjectARX

Đặt vấn đề
Nếu không có ứng dụng liên quan, làm thể nào để làm việc với bản vẽ có chứa nhiều thực thể proxy (custom entities). Hay làm thế nào để sử dụng dữ liệu trong bản vẽ, như là để xây dựng đối tượng hình học mới. Một vài thực thể có thể explode, nhưng một số khác lại không giống như không thể xóa được chúng vậy. Dù có được các thực thể AutoCAD tương đương nhưng những thực thể proxy vẫn còn đó. Cần phải làm gì?
Giải pháp
Hoàn toàn có thể dùng ObjectARX để chuyển mọi thực thể proxy thành bất cứ cái gì. Ví dụ sau sẽ lặp lại qua bản vẽ và đổi tất cả thực thể Proxy thành một block vo danh. Các block đó chưa đựng các thành phần đồ họa tương đương với thực thể Proxy. Lưu ý rằng việc làm đó không cho phép bạn tạo ra các thực thể mới để lấy được thông tin lưu giữ trong thực thể gốc.
AcDbObjectIdArray proxies;  

// Iterate through the records  
// Make a list of all the proxies, and then process them afterwards. 
AcDbBlockTable* pTable; 
acdbHostApplicationServices()->workingDatabase()->getBlockTable
                                                    (
                                                        pTable,
                                                        AcDb::kForRead
                                                    );
if(pTable == NULL)
    return

AcDbBlockTableIterator* pTableIter;
for( pTable->newIterator(pTableIter); !pTableIter->done(); pTableIter->step())
{     
    AcDbBlockTableRecord* pRecord;     
    pTableIter->getRecord(pRecord,AcDb::kForRead);  
    if(pRecord == NULL)
    {   
        acutPrintf(_T("\nCannot open a BTR"));  
        continue;   
    } 

    AcDbBlockTableRecordIterator* pRecordIter;
    for (    pRecord->newIterator(pRecordIter);
            ! pRecordIter->done();
            pRecordIter->step()
        )
    {
        AcDbEntity*pEnt;    
        pRecordIter->getEntity(pEnt, AcDb::kForRead);
        if(pEnt != NULL )
        {
            if( pEnt->isKindOf(AcDbProxyEntity::desc()))
            {        
                proxies.append(pEnt->objectId() );   
            }          
            pEnt->close();    
        }    
    }   
    delete pRecordIter;   
    pRecord->close(); 
}  

delete pTableIter;
if( Acad::eOk != pTable->upgradeOpen())
{   
    acutPrintf(_T("\nCannot open table for Write"));
    pTable->close();
    return;
}
int nProxies = proxies.length(); 
for( int i=0;i<nProxies; i++ )
    AcDbProxyEntity* pProxy;  
    AcDbObject* pObj;   
    acdbOpenAcDbObject(pObj, proxies[i], AcDb::kForRead);
    pProxy = AcDbProxyEntity::cast(pObj); 
    if( NULL == pProxy )
    {   
        pObj->close () ;  
        continue
    }    
    AcDbVoidPtrArray explodedEnts; 
    pProxy->explode(explodedEnts);
    int nExplodedEnts = explodedEnts.length();
    if( nExplodedEnts > 0 )
    {       
        AcDbBlockTableRecord*pRecord = new AcDbBlockTableRecord();
        pRecord->setName(_T("*B")); 
        AcDbObjectId blockId;   
        pTable->add(blockId, pRecord ); 
        for( int j=0; j<nExplodedEnts; j++)
        {        
            AcDbEntity*pEnt =(AcDbEntity*)(explodedEnts[j]);
            pRecord->appendAcDbEntity(pEnt);
            pEnt->setColorIndex(0);     
            pEnt->close();       
        }      
        pRecord->close(); 
        AcDbBlockTableRecord* pOwningRecord; 
        acdbOpenObject    (   
                            pOwningRecord,
                            pProxy->ownerId(),
                            AcDb::kForWrite
                        ); 
        if( NULL != pOwningRecord)
        {   
            AcDbBlockReference* pRef = new AcDbBlockReference; 
            pRef->setBlockTableRecord(blockId);      
            pOwningRecord->close();       
            pProxy->upgradeOpen();         
            pProxy->handOverTo(pRef); 
            pRef->setColor(pProxy->color()); 
            pRef->setLayer(pProxy->layerId()); 
            pRef->setVisibility(pProxy->visibility());
            delete pProxy;      
            pRef->close();       
        }     
    }     
    else
    { 
        pProxy->close();
    }  
}
pTable->close();


Link nguồn: Adndevblog

No comments:

Post a Comment

Featured Post

Lisp Copy tăng số trong AutoCAD | AutoLISP That la don gian

Ứng dụng được phát triển bởi đội ngũ AutoLISP Thật là đơn giản       Thông tin thêm: 👉👉👉

Popular Posts