Как мне получить свойства блока и изменить их? внутри pickfirstModified

Автор Тема: Как мне получить свойства блока и изменить их? внутри pickfirstModified  (Прочитано 13075 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн ОлегАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Добрый день.

Помогите пожалста с новым вопросом.

AcEditorReactor2::pickfirstModified() показывает выделенные объекты( примитивы и блоки).

 Как мне получить свойства блока и изменить их?

Например блок "Коробка для ананасов".
Он рисуется уже готовым блоком.
Мне нужно получить его Название, ширину, глубину и высоту.
Затем поменять размеры в 2 раза.

Сам пытаюсь но запутался. :-\

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Как мне получить свойства блока и изменить их?
Какие свойства блока?
Мне нужно получить его Название, ширину, глубину и высоту.
Название у блока есть. А вот понятия ширины, глубины и высоты для блока не существует. Что под ними подразумевается? Или может это вообще не блок? Давай пример чертежа, в котором эта "Коробка для ананасов".
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ОлегАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Я пробовал получить название как здесь описано
http://adn-cis.org/poluchenie-imeni-bloka-v-arx.html

Но почемуто его выводит как *U3 или другой номер.
И почемуто он всегда статический.

Насчет размеров это я понял уже - не получится.

А вот как получить название, слой, цвет, типы линий и прочее, я так понимаю весь состав примитивов входящих в блок?

Читаю Полищука, но там только просмотр блоков а не внутри блока который уже выделен или несколько блоков.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Я пробовал получить название как здесь описано
http://adn-cis.org/poluchenie-imeni-bloka-v-arx.html

Но почемуто его выводит как *U3 или другой номер.
И почемуто он всегда статический.

Примечание переводчика прочитал? Второй код проверил?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ОлегАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Именно второй код использовал.
Код дебагером прохожу.
По условию сразу на статический вариант переходит
но при том название как для динамического выводит, т.е. *U3


Приведу код только сильно не смейтесь
Код - C++ [Выбрать]
  1.  
  2.           ads_name sset;
  3.           int err = acedSSGet(_T("_I"), NULL, NULL, NULL, sset);
  4.           if (err != RTNORM)
  5.                   return;
  6.  
  7.           long i, length;
  8.           ads_name ename;
  9.           AcDbObjectId entId;
  10.  
  11.           acedSSLength(sset, &length);
  12.           for (i = 0; i < length; i++)
  13.           {
  14.                   acedSSName(sset, i, ename);
  15.                   acdbGetObjectId(entId, ename);
  16.  
  17.                   //PrintBlockName();
  18.                   //ads_name en; ads_point p;
  19.                   //AcDbObjectId eId;
  20.                   //acdbGetObjectId(eId, sset);
  21.                   AcDbObjectPointer<AcDbBlockReference>  pBlkRef(entId, AcDb::kForRead);
  22.                   //if (pBlkRef.openStatus() == Acad::eOk) {
  23.                   //AcDbObjectId idBlkTblRec = pBlkRef->blockTableRecord();
  24.                  
  25.                   AcDbDynBlockReference dynBlk(entId);
  26.                   if (dynBlk.isDynamicBlock())
  27.                   {
  28.                         AcDbBlockTableRecordPointer pBTR(dynBlk.dynamicBlockTableRecord(), AcDb::kForRead);
  29.                         if (pBTR.openStatus() == Acad::eOk)
  30.                         {
  31.                                 const ACHAR *blkName = NULL; pBTR->getName(blkName);
  32.                                 acutPrintf(_T("\nИмя динамического блока: \"%s\""), blkName);
  33.                         }
  34.                   }
  35.                   else
  36.                   {              
  37.                         AcDbBlockTableRecordPointer pBTR(pBlkRef->blockTableRecord(), AcDb::kForRead);
  38.                         const ACHAR *blkName = NULL; pBTR->getName(blkName);
  39.                         acutPrintf(_T("\nИмя статического блока: \"%s\""), blkName);
  40.                   }
  41.                   //}
  42.  
  43.                   //MyObject* pMyObject;
  44.                   //AcDbEntity * pMyObject;
  45.                   AcDbBlockTableRecord * pMyObject = NULL;
  46.                   //AcDbObject * pMyObject;
  47.  
  48.                   ACHAR * pBlockName;
  49.                   if (acdbOpenObject(pMyObject, entId, AcDb::kForRead) == Acad::eOk)
  50.                   {
  51.                           pMyObject->getName(pBlockName);
  52.                           //pMyObject->highlight();
  53.                           pMyObject->close();
  54.                          
  55.                           ads_printf(_T("\nOK"));
  56.  
  57.                   }
  58.                   AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
  59.                   AcDbObjectId eId = acdbSymUtil()->blockModelSpaceId(pDb);
  60.  
  61.                   ads_printf(_T("\n -----------   AcDbObjectId eId = acdbSymUtil()->blockModelSpaceId(pDb);"));
  62.           }
  63.           acedSSFree(sset);

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Убери проверку if (dynBlk.isDynamicBlock()) и попробуй без неё:
Код - C++ [Выбрать]
  1. AcDbBlockTableRecordPointer pBTR(dynBlk.dynamicBlockTableRecord(), AcDb::kForRead);
  2. if (pBTR.openStatus() == Acad::eOk)
  3. {
  4.         const ACHAR *blkName = NULL; pBTR->getName(blkName);
  5.         acutPrintf(_T("\nИмя динамического блока: \"%s\""), blkName);
  6. }
  7. else
  8. {              
  9.       AcDbBlockTableRecordPointer pBTR(pBlkRef->blockTableRecord(), AcDb::kForRead);
  10.       const ACHAR *blkName = NULL; pBTR->getName(blkName);
  11.       acutPrintf(_T("\nИмя статического блока: \"%s\""), blkName);
  12. }

Если у динамического блока масштабы по осям не одинаковы, то isDynamicBlock чаще всего возвращает false - я поставил об этом в известность ADN DevHelp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ОлегАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Не входит в условие
    if (pBTR.openStatus() == Acad::eOk)
проходит дальше.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не входит в условие
    if (pBTR.openStatus() == Acad::eOk)
проходит дальше.
Ну тогда очень вероятно, что блок не динамический, а анонимный. Или что-то в чертеже испорчено. Выложи чертеж с одним таким блоком.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ОлегАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Я так понимаю что с помощью строчек
Код - C++ [Выбрать]
  1.                   acedSSName(sset, i, ename);
  2.                   acdbGetObjectId(entId, ename);
  3.                   AcDbObjectPointer<AcDbBlockReference>  pBlkRef(entId, AcDb::kForRead);
получаю указатель на блок.
(i - счетчик в цикле for)

А как мне дальше в нем с помощью итератора пройтись по примитивам входящих в блок?
У Полищука все идет через открытие базы и т.д. , на блоках заканчивается.

« Последнее редактирование: 27-10-2015, 16:57:51 от Александр Ривилис »

Оффлайн ОлегАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Создал свой блок - круг и прямоугольник, дал имя.
Его имя выводит правильно.
Он определяется как статический.

А как это анонимный?
Прокси- объект?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А как это анонимный?
Частный случай анонимного блока - это вариант динамического при изменённых параметрах. Хотя есть еще варианты, когда возникают анонимные блоки. К прокси-объектам они не имеют никакого отношения.
А как мне дальше в нем с помощью итератора пройтись по примитивам входящих в блок?
Ты получил вставку блока (AcDbBlockReference). Теперь ты должен получить из неё запись таблицы блоков (AcDbBlockTableRecord) и по нему пройтись итератором.
Код - C++ [Выбрать]
  1. AcDbBlockTableRecordPointer pBlockDef(pBlkRef->blockTableRecord(), AcDb::kForRead);
  2. Acad::ErrorStatus es = pBlockDef.openStatus();
  3. AcDbBlockTableRecordIterator *pIterator = NULL;
  4. pBlockDef->newIterator(pIterator);
  5. for (pIterator->start(); !pIterator->done(); pIterator->step())
  6. {
  7.   AcDbObjectId idEnt;
  8.   pIterator->getEntityId(idEnt);
  9.   AcDbObjectPointer<AcDbEntity> pEnt(idEnt, AcDb::kForRead);
  10.   if (pEnt.openStatus() == Acad::eOk)
  11.   {
  12.     // Получаем свойства примитива в блоке (слой, цвет, типлинии и т.д.)
  13.   }
  14. }
  15. delete pIterator;
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ОлегАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Не могу разобраться что такое свойства блока и/или примитива.
Нашел то что у блока можно задавать атрибуты.
Это и есть свойства?
Например в каком слое лежат, координаты, название.
Нашел что атрибуты можно задавать.

Как их прочитать если атрибуты это и есть свойства?

Отмечено как Решение Олег 29-10-2015, 12:10:43

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Нашел то что у блока можно задавать атрибуты.
Это и есть свойства?
Нет. Атрибуты блока - это текстовая информация, обычно видимая при вставке блока.

Теперь объясни какие именно свойства тебя интересуют. Координаты для блока (точнее для вставки блока AcDbBlockReference) - возвращаются его методом AcDbBlockReference::position. Не уверен, что это то что тебе нужно. Слой примитива: AcDbEntity::layer (а AcDbBlockReference - наследник AcDbEntity). Как получить название блока ты должен быть уже в курсе. Что дальше?

P.S.: Без минимального знания AutoCAD (в эту категорию относится и что такое атрибуты блока) ты врядли сможешь дальше продвинуться.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ОлегАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Спасибо за помощь.
Я пока только вхожу в курс дела.

Все дело было в том что я искал эти свойства не в
    AcDbBlockReference
а в
    AcDbBlockTableRecordPointer
полагая что в данном случае я как раз и получаю доступ к блоку и всем его методам.

Извините за назойливость, но больше спросить не у кого.
Полищук в книге дает только самые азы, которые для начинающих полезные.
Но вот чтобы дальше копаться он не рассказывает всю структуру чертежа.

Мне главное ориентиры по которым в хелпе можно найти.
Вот в данном случае я и искал не там где надо .

Еще раз спасибо.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
а в
    AcDbBlockTableRecordPointer
полагая что в данном случае я как раз и получаю доступ к блоку и всем его методам.
Наверное всё-таки не AcDbBlockTableRecordPointer, а AcDbBlockTableRecord (т.к. AcDbBlockTableRecordPointer лишь "интеллектуальный указатель" на AcDbBlockTableRecord)
Имея доступ к AcDbBlockTableRecord вы получаете все примитивы, входящие в блок (в том числе и описанние атрибутов AcDbAttributeDefinition, из которых при вставке блока создаются атрибуты блока - AcDbAttribute) и соотвественно свойства этих примитивов (цвет, слой, тип линии и т.д.), а не блока целиком.
« Последнее редактирование: 29-10-2015, 13:56:49 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение