(изменено: Ю Николаев, 14 июня 2012г. 14:54:37)

Тема: Контекстное редактирование блока

Добрый день!!
При контекстном редактировании блока элементы, не входящие в состав блока, становятся тусклыми, но выбор их все равно возможен.

Подскажите пожалуйста как при контекстном редактировании блока определить входит ли выбранный элемент в состав блока.

Имя редактируемого блока можно получить из переменной - REFEDITNAME

Пример кода

void Select()
{
   ads_name  selection_set;
   acedSSGet(_T("_"), NULL, NULL, NULL, selection_set);

   CString block_ref_name;
   struct resbuf rb; 

   acedGetVar(_T("REFEDITNAME"), &rb); 
   block_ref_name=rb.resval.rstring;

   AcDbObjectIdArray block_ref_object_ids;
   if (!block_ref_name.IsEmpty())
   {
      AcDbObjectId block_ref_id=0;
      block_ref_id=GetBlockRef(block_ref_name, block_ref_object_ids); 

      long sel_count;
      acedSSLength(selection_set, &sel_count);
      for (int n=0; n<sel_count; n++) 
      {
         ads_name entity_name;
         acedSSName(selection_set, n, entity_name);

         AcDbObjectId obj_id;
         acdbGetObjectId(obj_id, entity_name);

         //  ?????
         // Здесь перебор по obj_id выбранного элемента входящего в блок и 
         // id элементов из block_ref_object_ids не дает никаких результатов
      }
  
   }

}

//Получение id блока и списка id элементов входящих в блок

AcDbObjectId GetBlockRef(CString BlocRefName, AcDbObjectIdArray& BlockRefObjectIds)
{
  AcDbBlockTable *p_block_table;
  AcDbBlockTableRecord *p_block_table_record;
  AcDbBlockTableIterator* p_block_table_iter;
  AcDbObjectId obj_id;

  Acad::ErrorStatus err_state;

  obj_id=0;

  acdbHostApplicationServices()->workingDatabase()->getSymbolTable(p_block_table, AcDb::kForRead);
  err_state=p_block_table->newIterator(p_block_table_iter);
        
  for (p_block_table_iter->start(); !p_block_table_iter->done(); p_block_table_iter->step()) 
  {
     err_state=p_block_table_iter->getRecord(p_block_table_record, AcDb::kForRead);

     const TCHAR* name;
     p_block_table_record->getName(name);
     
     if (BlocRefName.CompareNoCase(name)!=0)
     {
        p_block_table_record->close();
        continue;
     }

     obj_id=p_block_table_record->objectId();

     GetBlockEnts(p_block_table_record, BlockRefObjectIds);
     p_block_table_record->close();
  }

  delete p_block_table_iter;
  p_block_table->close();
  
  return obj_id;
}


// Получение списка id  элементов входящих в блок

void GetBlockEnts(AcDbBlockTableRecord* BlockTableRecord, AcDbObjectIdArray& BlockRefObjectIds)
{
    Acad::ErrorStatus err_state;
    AcDbObjectId obj_id;
    AcDbBlockTableRecordIterator* iter;

    BlockRefObjectIds.removeAll();

    err_state = BlockTableRecord->newIterator(iter, true);
    if (err_state != Acad::eOk)
    {
        return;
    }

    for (; !iter->done(); iter->step(true, true)) 
    {
        err_state = iter->getEntityId(obj_id);
        if (err_state == Acad::eOk)  BlockRefObjectIds.append(obj_id);
    }

    delete iter;
}

Я смотрел по форуму - есть похожие темы - получение id блока, списка id элементов, входящих в блок.
Но тему контекстном редактировании блока, к сожалению, не нашел

Может быть подскажете вариант как ограничиться только выбором элементов, входящих в редактируемый блок
- например в параметрах acedSSGet ????


Заранее спасибо

Re: Контекстное редактирование блока

что-то мне подсказывает, что это всё не поможет.
в справка акада написано, что объекты, кроме тех, из которых состоит блок примораживаются и их нельзя редактировать. как оказалось, нельзя их редактировать ТОЛЬКО командами акада, а так запросто :)
думаю копать нужно в сторону транзакций. т.к. только там вообще упоминается понятия рабочего набора (или как-то так).
AcApLongTransactionManager::currentLongTransactionFor - это для получения активной транзакции
AcDbLongTransaction::workSetHas - а это чтоб узнать, это объект рабочего набора транзакции или нет.
ну и собственно выбор ВСЕГО по идее остается, ток потом иды этих объектов нада подсосывать в workSetHas чтоб узнать подходит или нет

ну и второй вариант, например, попытаться переносить объекты по очереди на какой-то вектор акадовской командой MOVE. если переносится, то вернуть на место и добавить объект к выборке. ну а если не переноситься, то это не наш объект. повторюсь, ТОЛЬКО командой акада а не transformBy, т.к. трансформ отрабатывает для всех объектов, даже для "заблокированных".

PS: первый метод не тестировал, но исходя из справки так и надо поступить. второй проще для понимания, но больше строк кода. да и уж сильно обходной маневр в нем :):):)

Re: Контекстное редактирование блока

Спасибо.
Не стал пробовать второй метод, а через транзакции работает.