AcDbMLeader обновление текстового стиля

Автор Тема: AcDbMLeader обновление текстового стиля  (Прочитано 8989 раз)

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

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

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

  • ADN Club
  • ***
  • Сообщений: 156
  • Карма: 8
  • Skype: begiz_i
Добрый вечер,
Такая ситуация :
1. я создаю мултивыноски программно
2. с ними всё хорошо в плане отображения

НО! если я в настройках стиля выноски меняю например стиль текста (средствами автокада, не програмно),
то это изменение не отображается и не применяется к выноске пока я её не сдвину.

Если я создаю мултивыноску не програмно, это изменение отображается моментально

отсюда вывод, что я как-то не так или не до конца инициализирую выноску когда создаю програмно.
может там какой то реактор прицепить нужно или еще чтото?

Код - C++ [Выбрать]
  1. AcDbObjectPointer<AcDbMLeader> pMLeader;
  2. pMLeader.create();
  3. pMLeader->setDatabaseDefaults();
  4. pMLeader->addLeader(ibx);
  5. pMLeader->addLeaderLine(ibx, idx);
  6. pMLeader->addFirstVertex(idx, point1);
  7. pMLeader->addLastVertex(idx, point2);
  8.                
  9. pMLeader->setLayer(_T("Leaders"));
  10. pMLeader->setColorIndex(BYLAYER);
  11.                
  12.  
  13. AcDbMText * mText = new AcDbMText();
  14. mText->setDatabaseDefaults();
  15. mText->setContents(_T("TEST"));
  16. mText->setTextStyle(textStyleId);
  17. mText->setTextHeight(textHeight);
  18. mText->setLineSpacingStyle(AcDb::kExactly);
  19. mText->setLayer(pMLeader->layer());
  20. mText->setColorIndex(BYLAYER);
  21. pMLeader->setContentType(AcDbMLeaderStyle::kMTextContent);
  22. pMLeader->setMText(mText);
  23. delete mText;
  24. if (point1.x > point2.x)
  25.         {
  26.            pMLeader->setDoglegDirection(ibx, AcGeVector3d(-1, 0, 0));
  27.            pMLeader->setTextAlignmentType(AcDbMLeaderStyle::kRightAlignment);
  28.         }
  29.         else
  30.         {
  31.            pMLeader->setDoglegDirection(ibx, AcGeVector3d(1, 0, 0));
  32.            pMLeader->setTextAlignmentType(AcDbMLeaderStyle::kLeftAlignment);
  33.         }
  34.  
  35. pMLeader->setTextLocation(point2);
  36.  
  37. pMLeader->setMLeaderStyle(mlStyleId);
  38. pMLeader->updateLeaderLinePosition();
  39.  
  40. leaderId = addToDataBase(pMLeader);
  41. pMLeader->close();
  42.  

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я не увидел в этом коде вызова pMLeader->setTextStyleId(textStyleId)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
begiz,
Оказалось не всё так просто. Я поэкспериментировал и так и не смог повторить поведение, аналогичное тому как это происходит с MLEADER, созданным обычной командой AutoCAD. Отправил запрос в ADN DevHelp. По результатам отпишусь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение begiz 23-10-2021, 10:43:22

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Только отправил запрос в ADN DevHelp, как меня осенило, что требуется связать AcDbMLeaderStyle с AcDbMLeader - иначе как же ему знать, что требуется обновить AcDbMLeader после изменения AcDbMLeaderStyle. Думаю (хотя и не проверял), что это повлияет не только на изменение текстового стиля.
Код - C++ [Выбрать]
  1. static void RivilisCRML()
  2. {
  3.   int ibx = 0;
  4.   int idx = 0;
  5.   double textHeight = 5;
  6.   AcGePoint3d point1, point2;
  7.   if (acedGetPoint(NULL, _T("\nFirst point: "), asDblArray(point1)) != RTNORM ||
  8.       acedGetPoint(asDblArray(point1), _T("\nSecond point: "), asDblArray(point2)) != RTNORM)
  9.       return;
  10.   AcDbObjectPointer<AcDbMLeaderStyle> pMLStyle(acdbCurDwg()->mleaderstyle(), AcDb::kForRead);
  11.   AcDbObjectPointer<AcDbMLeader> pMLeader;
  12.   pMLeader.create();
  13.   pMLeader->setDatabaseDefaults();
  14.   AcDbObjectId leaderId = addToDataBase(pMLeader);
  15.  
  16.   pMLeader->addLeader(ibx);
  17.   pMLeader->addLeaderLine(ibx, idx);
  18.   pMLeader->addFirstVertex(idx, point1);
  19.   pMLeader->addLastVertex(idx, point2);
  20.  
  21.   // pMLeader->setLayer(_T("Leaders"));
  22.   pMLeader->setColorIndex(0);
  23.  
  24.   if (point1.x > point2.x)
  25.   {
  26.     pMLeader->setDoglegDirection(ibx, AcGeVector3d(-1, 0, 0));
  27.     pMLeader->setTextAlignmentType(AcDbMLeaderStyle::kRightAlignment);
  28.   }
  29.   else
  30.   {
  31.     pMLeader->setDoglegDirection(ibx, AcGeVector3d(1, 0, 0));
  32.     pMLeader->setTextAlignmentType(AcDbMLeaderStyle::kLeftAlignment);
  33.   }
  34.  
  35.   pMLeader->setTextLocation(point2);
  36.  
  37.   AcDbMText* mText = new AcDbMText();
  38.   mText->setDatabaseDefaults();
  39.   mText->setContents(_T("TEST"));
  40.   mText->setTextStyle(pMLStyle->textStyleId());
  41.   mText->setTextHeight(textHeight);
  42.   mText->setLineSpacingStyle(AcDb::kExactly);
  43.   mText->setLayer(pMLeader->layer());
  44.   mText->setColorIndex(0);
  45.   pMLeader->setContentType(AcDbMLeaderStyle::kMTextContent);
  46.   pMLeader->setMText(mText);
  47.   delete mText;
  48.  
  49.   pMLeader->updateLeaderLinePosition();
  50.   pMLeader->setTextStyleId(pMLStyle->textStyleId());
  51.   pMLeader->setOverride(AcDbMLeader::PropertyOverrideType::kTextStyleId, false);
  52.   pMLeader->setMLeaderStyle(acdbCurDwg()->mleaderstyle());
  53.   // Указываем MLeaderStyle, что от него зависит MLeader
  54.   if (pMLStyle->upgradeOpen() == Acad::eOk)
  55.   {
  56.     pMLStyle->addPersistentReactor(leaderId);
  57.   }
  58.  
  59. }

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

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

  • ADN Club
  • ***
  • Сообщений: 156
  • Карма: 8
  • Skype: begiz_i
Спасибо Александр!
всё заработало!

не подскажите где можно про эти реакторы почитать?
в документации ничего ценного нету

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
всё заработало!
Отлично!
не подскажите где можно про эти реакторы почитать?
В том то и дело, что нигде. Точнее, в документации есть про метод addPersistentReactor, но поди догадайся, что его следует использовать с AcDbMLeaderStyle...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ***
  • Сообщений: 156
  • Карма: 8
  • Skype: begiz_i
Цитировать
В том то и дело, что нигде. Точнее, в документации есть про метод addPersistentReactor, но поди догадайся, что его следует использовать с AcDbMLeaderStyle...
жаль, очень жаль...

с новыми выносками всё работает.
но уже наделано куча чертежей, где это сделано не правельно
я думал что просто добавив такую функцию смогу обновить все выноски до нормального состояния, но чтото почемуто не работает...

Код - C++ [Выбрать]
  1. std::map<int, std::map<CString, CString>> all_map = GraphTools::findAllByTypeMap();
  2.                 AcDbObjectId mlStyleId = GraphTools::getMLeaderStyle(LEADER_STYLE);
  3.                 AcDbObjectId textStyleId = GraphTools::getTextStyleFromLeaderStyle(mlStyleId);
  4.                 AcDbObjectPointer<AcDbMLeaderStyle> pMLStyle(mlStyleId, AcDb::kForRead);
  5.                 if (pMLStyle->upgradeOpen() == Acad::eOk)
  6.                 {
  7.                         for (std::map<CString,CString>::iterator it = all_map[LEADER_TYPE].begin(); it!= all_map[LEADER_TYPE].end(); it++)
  8.                         {
  9.                                 AcDbObjectId leaderId = GraphTools::getObjectIdFromHandle(it->first);
  10.  
  11.                                 pMLStyle->removePersistentReactor(leaderId);
  12.                                 pMLStyle->addPersistentReactor(leaderId);
  13.  
  14.                                 AcDbObjectPointer<AcDbMLeader> mLeader(leaderId,AcDb::kForWrite);
  15.                                 if (mLeader.openStatus() == Acad::eOk)
  16.                                         mLeader->setTextStyleId(textStyleId);
  17.                                
  18.                         }
  19.                 }
  20.  

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
begiz,
Думаю, что не хватает:
Код - C++ [Выбрать]
  1. mLeader->setOverride(AcDbMLeader::PropertyOverrideType::kTextStyleId, false);
Т.е. ты должен указать, что текстовый стиль в MLeader не переопределен и должен браться из MLeaderStyle
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ***
  • Сообщений: 156
  • Карма: 8
  • Skype: begiz_i
спасибо!

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

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

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

  • ADN Club
  • ***
  • Сообщений: 156
  • Карма: 8
  • Skype: begiz_i
Re: AcDbMLeader обновление текстового стиля
« Ответ #10 : 23-10-2021, 15:49:29 »
да, попробовал и всё работает
только еще это добавил:
Код - C++ [Выбрать]
  1. mLeader->setOverride(AcDbMLeader::PropertyOverrideType::kTextHeight, false);
  2.  

я так понимаю что такой же механизм и для стилей таблиц должен работать?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: AcDbMLeader обновление текстового стиля
« Ответ #11 : 23-10-2021, 15:54:53 »
я так понимаю что такой же механизм и для стилей таблиц должен работать?
Теоретически да. Но нужно проверять.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: AcDbMLeader обновление текстового стиля
« Ответ #12 : 28-10-2021, 23:13:00 »
Спасибо Александр!
всё заработало!
Я забыл сразу отписаться в ADN DevHelp, что нашел решение проблемы. А они вчера написали, что не нашли решения и поэтому создали запрос команде инженеров на изменение поведения AutoCAD. И были очень обрадованы, что решение нашлось и достаточно простое. :)
« Последнее редактирование: 29-10-2021, 13:50:14 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ***
  • Сообщений: 156
  • Карма: 8
  • Skype: begiz_i
Re: AcDbMLeader обновление текстового стиля
« Ответ #13 : 29-10-2021, 12:08:43 »
Александр, вы круче ADN  :)

Кстати с стилем таблиц тоже вроде все работает