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

11/12/2013

Выбор определенных примитивов из набора предварительного выбора

Системная переменная 'PICKFIRST' будучи установленной в '1' позволяет пользователю выбрать примитивы до запуска команды AutoCAD. Это применимо и к командам, созданным при помощи ObjectARX.

Есть две ARX-функции, которые позволяют получить набор предварительного выбора. Это функция acedSSGet() с опцией "_I", и чаще используемая функция acedSSGetFirst(). Это демонстрирует следующий код. Имя команды 'pfss'.

Если пользователь предварительно выберет примитивы и запустит команду 'pfss', эти примитивы попадут в набор 'pfSet'. Проверим , что число элементов в наборе больше нуля и если это так, то выполним цикл 'for'. В цикле 'for' получаем ObjectId каждого примитива и открываем примитив «для чтения». Проверяем примитив при помощи функции 'isA()'. Вы можете аналогично проверить и пользовательские примитивы если замените имя на имя пользовательского класса.

Можно использовать методы 'cast()' или 'isKindOf()'. Обратитесь к документации ObjectARX за описанием этих методов. Если примитив AcDbLine (или пользовательский примитив) переменная 'lineEntCount' увеличивается. Примитив закрывается и переходим к следующему примитиву. Результаты сообщаются пользователю. Функция acedSSGetFirst()

Функция acedSSGetFirst () показана в конце фрагмента кода. Эта функция требует двух указателей на списки буферов результатов, первый 'prbGrip' содержит примитивы, у которых подсвечены «ручки», но не выбраны, а второй 'prbPick' содержит примитивы, которые предварительно выбраны. Если ни один примитив не был предварительно выбран, то поле 'ResType' списка буферов 'prbPick' будет содержать значение 'RTNONE'. Если примитивы были предварительно выбраны то поле 'ResType "поле будет содержать значение 'RTPICKS'. Если это так, то поле resval.rlname буфера результата будет содержать набор объектов. Не забудьте освободить наборы выбора, прежде освободить списки буферов результатов.

Код - C++: [Выделить]
  1. void pfss()
  2. {
  3.   AcDbEntity *pEnt;
  4.   AcDbObjectId entId;
  5.   Acad::ErrorStatus es;
  6.   int retCode;
  7.   ads_name pfSet; // 'PICKFIRST' набор выбора
  8.   ads_name ename; long pfSetLen;
  9.   // Количество примитивов в наборе 'PICKFIRST'
  10.   long lineEntCount = 0;
  11.   acedSSGet(L"_I", NULL, NULL, NULL, pfSet);
  12.   acedSSLength(pfSet, &pfSetLen);
  13.   // Проверим, что набор не пустой
  14.   if(pfSetLen > 0)
  15.   {
  16.     acutPrintf(L"\nПредварительно выбрано %d примитивов.",     pfSetLen);
  17.     // Цикл по примитивам в наборе
  18.     for(long i = 0; i < pfSetLen; i++)
  19.     {
  20.       retCode = acedSSName(pfSet, i, ename);
  21.       if(retCode != RTNORM)
  22.       {
  23.         acutPrintf(L"\nОшибка получения примитива из набора");
  24.         break;
  25.       }
  26.       es = acdbGetObjectId(entId, ename);
  27.       if(es != Acad::eOk)
  28.       {
  29.         acutPrintf(L"\nОшибка получения AcDbObjectId примитива.");
  30.         break;
  31.       }
  32.       es = acdbOpenAcDbEntity(pEnt, entId, AcDb::kForRead);
  33.       if(es != Acad::eOk)
  34.       {
  35.         acutPrintf(L"\nОшибка открытия примитива для операции чтения");
  36.         break;
  37.       }
  38.       // Здесь мы проверяем в точности на примитив AcDbLine.
  39.       // Точно так же мы можем проверить на пользовательский примитив,
  40.       // являющийся элементов в дереве иерархии классов.
  41.       // Мы можем использовать методы cast() и isKindOf()
  42.       // Обратите внимание на идентификацию времени выполнения (RTI)
  43.       // в документации ObjectARX, описывающую эти методы
  44.       if(pEnt->isA() == AcDbLine::desc())
  45.       {
  46.         // Увеличим счетчик отрезков
  47.         lineEntCount++;
  48.       }
  49.       // Не забываем закрывать примитив, когда заканчиваем
  50.       // работать с ним.
  51.       pEnt->close();
  52.     } // for
  53.     acutPrintf(L"\nВсего в наборе %d примитивов класса AcDbLine.",  lineEntCount);
  54.   }
  55.   else
  56.   {
  57.     acutPrintf(L"\nНичего не было предварительно выбрано.");
  58.   }
  59.   // Не забываем освободить набор.
  60.   acedSSFree(pfSet);
  61.   // Здесь мы продемонстрируем использование функции acedSSGetFirst()
  62.   // для получения набора предварительного выбора.
  63.   // prbGrip - resbuf содержащий набор примитивов,
  64.   // у кооторого подсвечены ручки, но примитивы не выбраны.
  65.   // prbPick - resbuf содержит набор в resval.rlname
  66.   // предварительно выбранных примитивов.
  67.   // Ручки могут быть, а могут и не быть.
  68.   struct resbuf* prbGrip = NULL;
  69.   struct resbuf* prbPick = NULL;
  70.   // олучаем наборы
  71.   acedSSGetFirst(&prbGrip, &prbPick);
  72.   long gripLen, pickLen;
  73.   acedSSLength(prbPick->resval.rlname, &pickLen);
  74.   acedSSLength(prbGrip->resval.rlname, &gripLen);
  75.   acutPrintf(
  76.     L"\nПредварительно выбрано %d  примитивов - результат функци acedSSGetFirst().",
  77.     pickLen);
  78.   // Не забываем освободить наборы.
  79.   acedSSFree(prbPick->resval.rlname);
  80.   acedSSFree(prbGrip->resval.rlname);
  81.   // А также освобождаем списки результатов
  82.   acutRelRb(prbGrip);
  83.   acutRelRb(prbPick);
  84. }

Источник: http://adndevblog.typepad.com/autocad/2013/01/selecting-specific-entities-from-a-pickfirst-selection-set.html

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

Опубликовано 11.12.2013
Отредактировано 11.12.2013 в 05:09:52