Изменения в например позиции AcDbBlockReference не отображается на чертеже

Автор Тема: Изменения в например позиции AcDbBlockReference не отображается на чертеже  (Прочитано 17852 раз)

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

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

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

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не вижу кода, не знаю контекста. По кофейной гуще не гадаю.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Код - C++ [Выбрать]
  1. void EditorReactor::pickfirstModified()
  2. {
  3. // бла бла - получаем выделенный элемент
  4.  
  5.                   AcDbObjectPointer<AcDbObject>  pObj(objId, AcDb::kForRead);
  6.  
  7.                   if ( pObj->isKindOf(AcDbBlockReference::desc()))
  8.                   {
  9.                           AcDbObjectPointer<AcDbBlockReference>  pBlkRef(objId, AcDb::kForRead);
  10.                           BlockInfo(pBlkRef);
  11.                           pBlkRef->close();
  12.                   }  
  13. }
  14. void BlockInfo(AcDbBlockReference * pBlkRef)
  15. {
  16.         acutPrintf(_T("\n-----------Это блок---------"));
  17.         AcGePoint3d p3d(pBlkRef->position());
  18.         acutPrintf(_T("\nКоординаты блока: X:%7.1f,  Y:%7.1f,  Z:%7.1f"), p3d.x, p3d.y, p3d.z);
  19.  
  20.         acutPrintf(_T("\nИндекс цвета  блока %d"), pBlkRef->colorIndex());
  21.  
  22.         AcGePoint3d p3d2(pBlkRef->position());
  23.         Adesk::UInt16 newColor = pBlkRef->colorIndex();
  24.  
  25.         pBlkRef->upgradeOpen();
  26.  
  27.         AcGePoint3d p3d_2(p3d2.x + 1000, p3d2.y, p3d2.z);
  28.         pBlkRef->setPosition(p3d_2);
  29.         acutPrintf(_T("\nНовые Координаты блока: X:%7.1f,  Y:%7.1f,  Z:%7.1f"), p3d_2.x, p3d_2.y, p3d_2.z);
  30.        
  31.         newColor++;
  32.         if (newColor >= 255) newColor = 1;
  33.         pBlkRef->setColorIndex(newColor);
  34.        
  35.         acutPrintf(_T("\nНовый индекс цвета  блока %d"), pBlkRef->colorIndex());
  36.  
  37.         pBlkRef->downgradeOpen();
  38. }
  39.  

В результате ни координаты не меняются ни цвет  ни цвета линий.
Изменения цвета линий осуществляются в еще одной вызываемой функции. Здесь она не представлена для простоты чтения кода.
Если подобную последовательность использовать для примитивов например линий то и цвет их меняется и позиция.
И даже без upgradeOpen() и downgradeOpen().
« Последнее редактирование: 23-11-2015, 17:29:44 от Олег »

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

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

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

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
в реакторе.
пример немного изменил.

а как тогда менять то?
подскажите пожалста

Отмечено как Решение Олег 24-11-2015, 13:15:56

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

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Я сделал тестовый проект и записал видео:



Пару замечаний:
1. В самом реакторе pickfirstModified крайне (!!!) нежелательно модифицировать примитивы. Ты вообще в AutoCAD видел чтобы так делалось? Я за 25 лет работы с AutoCAD такого не видел. Это противоречит общепринятому в AutoCAD подходу.
Я сделал этот пример только для того, чобы было понятно как это можно сделать. Если выбрана вставка блока с именем TESTBLK, то она сдвигается  на (10, 10, 0) и меняет индекс цвета на 1.
2. Поменять цвет вставке блока можно, но (!!!) видно это будет только если примитив (или примитивы) внутри определения блока имеют цвет "ПоБлоку" ("byBlock"). В противном случае их цвет останется тем же, что и был. Учи AutoCAD!!!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А вот так принято делать в AutoCAD:



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

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

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

Спасибо за примеры и видео. Все наглядно и понятно.
По поводу запрета изменений свойств внутри реактора я так понимаю это следует из принципа что в обработчике событий нельзя делать то что может снова вызвать событие. Верно?

И еще один вопрос по вашему примеру.
Вы в правильном примере используете выбор элемента (acedSSLength) 2 раза.
Насколько правильно было бы в  AutoCAD использовать указатель на выбранный элемент?
Имею ввиду.
В реакторе по событию фокуса на элементе получить на него указатель.
Затем, у меня окно проперти, в окне меняю какоето свойство и оно применяется к элементу по указателю.
Соответственно указатель в null если элемент теряет фокус.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Насколько правильно было бы в  AutoCAD использовать указатель на выбранный элемент?
Так делать очень не рекомендую. Следует придерживаться принципа: открывать объект/примитив только тогда, когда нужно получить из него информацию или изменить его и сразу же закрывать. Во всяком случае перед тем как твоя программа возвращает управление AutoCAD ты должен закрыть все открытые тобой объекты. Иначе проблем не оберёшься. Особенно если открывал объект для ForWrite.
По поводу запрета изменений свойств внутри реактора я так понимаю это следует из принципа что в обработчике событий нельзя делать то что может снова вызвать событие. Верно?
Упрощенно - верно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вы в правильном примере используете выбор элемента (acedSSLength) 2 раза.
Эта функция получает количество элементов в наборе (в данном случае в наборе предварительного выбора - pickfirst).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
А разве элемент остается открытым если на него получен указатель?
Или скажем так если я его закрываю то указатель теряется?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А разве элемент остается открытым если на него получен указатель?
Конечно. Закрывает его метод close() (или деструктор AcDbObjectPointer - он вызвает метод close()). После вызова close() объект становится недействительным и указатель ссылается на область памяти, которая уже не является объектом (сравни с операторами new/delete)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 79
  • Карма: 0
Ну да, логично.
Спасибо за разъяснения, теперь более понятен принцип.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну да, логично.
Спасибо за разъяснения, теперь более понятен принцип.
Добавлю еще один существенный момент. Открыть объект ForRead можно 256 раз не закрывая, а вот открыть ForWrite можно только один раз, причем если этот объект еще ни разу не открыт ни ForRead, ни ForWrite. Именно по этой причине - перестал быть нужен объект - сразу его закрываем.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение