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

05/07/2013

Как использовать длинные транзакции для эмуляции команды -ССЫЛРЕД

Команды  -ССЫЛРЕД (-REFEDIT) и ССЫЛРЕД (REFEDIT) обеспечивают возможность контекстного редактирования блока (по месту). Они позволяют переключатся между вложенными ссылками блока. Тогда AutoCAD принимает подсвеченную вставку блока для редактирования по месту. Приложение посылает команду -ССЫЛРЕД для переключения в режим редактирования для удобства пользователя.

На самом деле, мы могли бы имитировать команду –ССЫЛРЕД длинными транзакциями. Классы и методы длинных транзакций обеспечивают схему редактирования примитивов, которая позволяет вытащить примитивы для редактирования и затем вернуть их обратно на прежнее место. Эта операция заменяет исходные примитивы на отредактированные, что очень полезно для редактирования блока, который мы хотим изменить на месте.

Следующий код подразумевает, что в вставке большого блока есть вставка маленького блока. Код предоставляет нам две команды: testcheckout просит нас указать примитивы в вставке маленького блока, затем получает вставку большого блока для редактирования по месту. Это только демо без достаточного числа проверок на ошибки.

Больше информации есть в ObjectARX документации и в примере SDK\samples\database\longtrans_dg.

Код - C++: [Выделить]
  1.  
  2. // Глобальные переменные для двух команд checkout и checkin
  3. // ID длинной транзакции
  4. AcDbObjectId long_trans_id;
  5. // errorMap длинной транзакции
  6. AcDbIdMapping error_map;
  7. /////////////////////////////////////////////////////////
  8. //  команда: testcheckout
  9. //
  10. //  указываем примитивы вставки малого блока
  11. //  принимаем вставку большого блока для редактирования по месту
  12. ///////////////////////////////////////////////////////
  13.  
  14. static void ADNSample_testcheckout(void)
  15. {
  16.   //  Это исправленное демо, не забудьте указать примитивы
  17.   //  вставки малого блока
  18.   ads_name ename;
  19.   ads_point ptResult;
  20.   ads_matrix adsmat;
  21.   struct resbuf *info;
  22.   AcDbObjectId ownerId;
  23.  
  24.   int rt =
  25.     acedNEntSelP(_T("\nВыберите примитив малого блока:"),
  26.     ename,ptResult, false ,adsmat, &info);
  27.  
  28.   if( rt!= RTNORM)
  29.   {
  30.     acutPrintf(_T("\nОшибка в acedNEntSelP"));
  31.     return;
  32.   }
  33.  
  34.   if(info == NULL)
  35.   {
  36.     acutPrintf(_T("\n Нет информации!"));
  37.     return;
  38.   }        
  39.  
  40.   //  Выбранные примитивы могут находится в вложенных вставках.       
  41.   //  в этом примере: большая вставка и малая вставка
  42.   //  Массив всех id вставок
  43.  
  44.   AcDbObjectIdArray owner_Entity_idArray;
  45.   struct resbuf *rbIter = info;
  46.   ads_name tempName;
  47.   AcDbObjectId objId;        
  48.  
  49.   while (rbIter != NULL) {
  50.     tempName[0] = rbIter->resval.rlname[0];
  51.     tempName[1] = rbIter->resval.rlname[1];
  52.     acdbGetObjectId(objId, tempName);
  53.     owner_Entity_idArray.append(objId);
  54.     rbIter = rbIter->rbnext;
  55.   }
  56.  
  57.   acutRelRb(info);
  58.  
  59.   //  В этом примере второй – это вставка большого блока
  60.   AcDbObjectId big_ref_id = owner_Entity_idArray[1];
  61.   //  итерация по примитивам владельца.
  62.   AcDbObjectIdArray  parentBlkEntArr;
  63.   AcDbObjectId big_ref_rec_id;
  64.   AcDbObject *pObj = NULL;
  65.   //  Открываем вставку большого блока       
  66.   Acad::ErrorStatus es =
  67.     acdbOpenObject(pObj,big_ref_id,AcDb::kForRead);
  68.   if(Acad::eOk == es)
  69.   {
  70.     if(pObj->isKindOf(AcDbBlockReference::desc()))
  71.     {               
  72.       //  получаем id определения вставки большого блока
  73.       big_ref_rec_id =
  74.         ((AcDbBlockReference*)pObj)->blockTableRecord();
  75.     }
  76.     pObj->close();
  77.   }   
  78.   //  готовим объекты для check out.
  79.   //  Обратите внимание: объектами checkout являются
  80.   //  примитивы определения блока
  81.   //  открываем определение вставки большого блока
  82.  
  83.   es = acdbOpenObject(pObj,big_ref_rec_id,AcDb::kForWrite);
  84.   if(es != Acad::eOk) return;
  85.  
  86.   AcDbBlockTableRecord *big_ref_rec =
  87.     (AcDbBlockTableRecord*)pObj;
  88.   //  Покажем имя блока, которое будем редактировать по месту
  89.   const ACHAR *ref_rec_name = NULL;
  90.   big_ref_rec->getName(ref_rec_name);
  91.   TCHAR msg[256] = {0};
  92.   _tcscat( msg,L"Блок который будем редактировать по месту: ");
  93.   _tcscat( msg, ref_rec_name );
  94.   MessageBox(NULL,msg,msg,0);      
  95.  
  96.   AcDbObjectIdArray objIdArray;   
  97.  
  98.   AcDbBlockTableRecordIterator *pIter;
  99.  
  100.   big_ref_rec->newIterator(pIter);
  101.  
  102.   //  получаем примитивы в определении блока
  103.   for (pIter->start(); !pIter->done(); pIter->step())
  104.   {
  105.     AcDbEntity *pEntity;
  106.     pIter->getEntity(pEntity, AcDb::kForRead);       
  107.     objIdArray.append(pEntity->objectId());       
  108.     pEntity->close();
  109.   }
  110.  
  111.   delete pIter;
  112.  
  113.   big_ref_rec->close();
  114.  
  115.   //  получаем id пространства модели
  116.  
  117.   AcDbBlockTable *pThisBlockTable;
  118.   acdbHostApplicationServices()->workingDatabase()
  119.     ->getSymbolTable(pThisBlockTable, AcDb::kForRead);
  120.  
  121.   AcDbBlockTableRecord *pThisMsBtr;
  122.  
  123.   pThisBlockTable->getAt(ACDB_MODEL_SPACE,
  124.  
  125.     pThisMsBtr, AcDb::kForWrite);
  126.  
  127.   pThisBlockTable->close();
  128.  
  129.   AcDbObjectId model_space_id = pThisMsBtr->objectId();
  130.  
  131.   pThisMsBtr->close();
  132.  
  133.   //  Выполняем check out
  134.  
  135.   acapLongTransactionManagerPtr()->checkOut(long_trans_id,
  136.  
  137.     objIdArray, model_space_id, error_map);
  138.  
  139.   //  теперь мы будем видеть вставку большого блока
  140.   //  как редактируемую по месту
  141.   //  ее можно редактировать вручную средствами AutoCAD
  142.  
  143. }
  144.  
  145. ///////////////////////////////////////////////
  146. //  Команда: testcheckin
  147. //
  148. //  check in длинную транзакцию для
  149. //  закрепления результатов редактирования
  150. // 
  151. ////////////////////////////////////////////
  152.  
  153. static void ADNSample_testcheckin(void)
  154. {       
  155.   // check in
  156.   acapLongTransactionManagerPtr()->checkIn(
  157.     long_trans_id, error_map);
  158. } 
  159.  

Источник: http://adndevblog.typepad.com/autocad/2012/04/-mimic-the-workflow-of-refedit-by-long-transaction.html

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

Опубликовано 05.07.2013
Отредактировано 04.08.2013 в 16:31:43