ADN Open CIS
Сообщество программистов Autodesk в СНГ

18/12/2013

Удаление всех прокси-примитивов из чертежа средствами ObjectARX

Вопрос:

Я хочу работать с чертежом, содержащем пользовательские объекты, для которых у меня нет соответствующего приложения. Я бы хотел использовать данные из чертежа для построения новой «геометрии».  Какие-то примитивы можно расчленить, а какие-то нет. И они отмечены как неудаляемые.  Я создаю эквивалент для этих примитивов, а вот удалить их не могу. Возможно ли их удалить?

Ответ                                                         
Средствами ObjectARX можно заменить прокси-примитивы на какие-то другие. Следующий код делает именно это: проходит по всем примитивам чертежа, переключая все прокси-примитивы на анонимные блоки. Блоки содержат эквивалентную геометрию прокси-примитивов. Заметим, что нельзя создать примитив содержащий ту же информацию, что и исходный примитив.

Код - C++: [Выделить]
  1. void RemoveProxy()
  2. {
  3.   AcDbObjectIdArray proxies;  
  4.  
  5.   // Проходим по всем записям  
  6.   // Создаём список всех прокси, а обработаем их потом. 
  7.   AcDbBlockTable* pTable; 
  8.   acdbHostApplicationServices()->
  9.     workingDatabase()->getBlockTable( pTable, AcDb::kForRead);
  10.   if(pTable == NULL)
  11.     return; 
  12.  
  13.   AcDbBlockTableIterator* pTableIter;
  14.   for( pTable->newIterator(pTableIter); !pTableIter->done(); pTableIter->step())
  15.   {     
  16.     AcDbBlockTableRecord* pRecord;     
  17.     pTableIter->getRecord(pRecord,AcDb::kForRead);  
  18.     if(pRecord == NULL)
  19.     {   
  20.       acutPrintf(_T("\nНе открывается BTR"));  
  21.       continue;   
  22.     } 
  23.  
  24.     AcDbBlockTableRecordIterator* pRecordIter;
  25.     for (pRecord->newIterator(pRecordIter); !pRecordIter->done(); pRecordIter->step())
  26.     {
  27.       AcDbEntity*pEnt;    
  28.       pRecordIter->getEntity(pEnt, AcDb::kForRead);
  29.       if(pEnt != NULL )
  30.       {
  31.         if( pEnt->isKindOf(AcDbProxyEntity::desc()))
  32.         {        
  33.           proxies.append(pEnt->objectId() );   
  34.         }          
  35.         pEnt->close();    
  36.       }    
  37.     }   
  38.     delete pRecordIter;   
  39.     pRecord->close(); 
  40.   }  
  41.  
  42.   delete pTableIter;
  43.   if( Acad::eOk != pTable->upgradeOpen())
  44.   {   
  45.     acutPrintf(_T("\nНе могу открыть таблицу для записи"));
  46.     pTable->close();
  47.     return;
  48.   }
  49.   int nProxies = proxies.length(); 
  50.   for( int i=0;i<nProxies; i++ )
  51.   { 
  52.     AcDbProxyEntity* pProxy;  
  53.     AcDbObject* pObj;   
  54.     acdbOpenAcDbObject(pObj, proxies[i], AcDb::kForRead);
  55.     pProxy = AcDbProxyEntity::cast(pObj); 
  56.     if( NULL == pProxy )
  57.     {   
  58.       pObj->close () ;  
  59.       continue; 
  60.     }    
  61.     AcDbVoidPtrArray explodedEnts; 
  62.     pProxy->explode(explodedEnts);
  63.     int nExplodedEnts = explodedEnts.length();
  64.     if( nExplodedEnts > 0 )
  65.     {       
  66.       AcDbBlockTableRecord*pRecord = new AcDbBlockTableRecord();
  67.       pRecord->setName(_T("*B")); 
  68.       AcDbObjectId blockId;   
  69.       pTable->add(blockId, pRecord ); 
  70.       for( int j=0; j<nExplodedEnts; j++)
  71.       {        
  72.         AcDbEntity*pEnt =(AcDbEntity*)(explodedEnts[j]);
  73.         pRecord->appendAcDbEntity(pEnt);
  74.         pEnt->setColorIndex(0);      
  75.         pEnt->close();       
  76.       }      
  77.       pRecord->close(); 
  78.       AcDbBlockTableRecord* pOwningRecord; 
  79.       acdbOpenObject(pOwningRecord, pProxy->ownerId(), AcDb::kForWrite); 
  80.       if( NULL != pOwningRecord)
  81.       {   
  82.         AcDbBlockReference* pRef = new AcDbBlockReference; 
  83.         pRef->setBlockTableRecord(blockId);      
  84.         pOwningRecord->close();       
  85.         pProxy->upgradeOpen();         
  86.         pProxy->handOverTo(pRef); 
  87.         pRef->setColor(pProxy->color()); 
  88.         pRef->setLayer(pProxy->layerId()); 
  89.         pRef->setVisibility(pProxy->visibility());
  90.         delete pProxy;      
  91.         pRef->close();       
  92.       }     
  93.     }     
  94.     else
  95.     { 
  96.       pProxy->close();
  97.     }  
  98.   }
  99.   pTable->close();
  100. }

Источник: http://adndevblog.typepad.com/autocad/2012/06/remove-all-proxy-entities-from-a-drawing-using-objectarx.html

Примечание переводчика: этот код обрабатывает только прокси-примитивы, но не прокси-объекты.

Обсуждение: http://adn-cis.org/forum/index.php?topic=404

Опубликовано 18.12.2013