pText->worldDraw(mode) возвращает true для AcDbMText

Автор Тема: pText->worldDraw(mode) возвращает true для AcDbMText  (Прочитано 9857 раз)

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

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

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

  • ADN Club
  • **
  • Сообщений: 81
  • Карма: 0
Добрый день.
Заметил, что у меня в методе subWorldDraw(AcGiWorldDraw *mode)
в коде
Код - C++ [Выбрать]
  1. AcDbMText* pText = new AcDbMText();
  2. pText->setBackgroundFill(true);
  3. pText->setUseBackgroundColor(false);
  4. pText->setBackgroundScaleFactor(1.0);
  5. pText->setBackgroundFillColor(backColor);
  6. pText->setRotation(ang);
  7. pText->setLocation(pos);
  8. pText->setContents(text);
  9. pText->setTextHeight(2.5);
  10. pText->setAttachmentMovingLocation(AlignLoc);
  11. pText->setTextStyle(styleId);
  12. pText->setPropertiesFrom(this);
  13. pText->worldDraw(mode);
  14. delete pText;
  15. pText = NULL;
строка
Код - C++ [Выбрать]
  1. pText->worldDraw(mode);
всегда возвращает true,
при этом текст отображается без ошибок.
Нормально ли такое поведение, или AcDbMText лучше
рисовать в методе subViewportDraw(AcGiViewportDraw* mode)?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Нормально ли такое поведение, или AcDbMText лучше
рисовать в методе subViewportDraw(AcGiViewportDraw* mode)?
Нормально не создавать и не удалять объекты в методах subWorldDraw/subViewportDraw. Но если работает и проблем не вызывает, то так и оставляй.
Кстати, советую проверить в разных VisualStyle и разных версиях AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 81
  • Карма: 0
Нормально не создавать и не удалять объекты в методах subWorldDraw/subViewportDraw.
А как тогда нарисовать текст с выравниванием, допустим, середина справа?
mode->geometry().text(...); такой возможности не предусматривает?

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

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

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

  • ADN Club
  • **
  • Сообщений: 81
  • Карма: 0
Понятно. То есть вполне допустимо создать в классе всего один AcDbMText, и даже если мне нужно отобразить около 20 подписей, просто
модифицировать этот же MText и выполнять для него каждый раз worldDraw?

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

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

Отмечено как Решение Gennadiy 01-08-2016, 17:50:19

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А как тогда нарисовать текст с выравниванием, допустим, середина справа?
mode->geometry().text(...); такой возможности не предусматривает?
Кстати, это можно сделать. Предварительно следует вычислить BoundingBox для текста, а затем уже его спозиционировать:
Код - C++ [Выбрать]
  1. Adesk::Boolean cxDbEmbeddedEntity::subWorldDraw (AcGiWorldDraw *mode) {
  2.   //////////////////////////////////////////////////////////////////////////
  3.   // Следующие три определения могут быть на уровне класса
  4.   //////////////////////////////////////////////////////////////////////////
  5.   AcDbObjectId styleId = id().database()->textstyle();
  6.   AcString text = _T("Тест");
  7.   AcGePoint3d pRightCenter; // Ты знаешь точку правой границы.
  8.   //////////////////////////////////////////////////////////////////////////
  9.   assertReadEnabled () ;
  10.   AcGiTextStyle style;
  11.   // Получаем текстовый стиль
  12.   Acad::ErrorStatus es = fromAcDbTextStyle(style, styleId);
  13.   style.loadStyleRec();
  14.   //
  15.   if (es == Acad::eOk)
  16.   {
  17.     // setup the text
  18.     int length = -1;
  19.     // find out the extents
  20.     AcGePoint2d extMax,extMin;
  21.     if (Acad::eOk == style.extentsBox(text, false, length, false, extMin, extMax))
  22.     {
  23.       // Вычисляем точку вставки
  24.       AcGePoint3d insertionPnt = pRightCenter -
  25.         AcGeVector3d(extMax.x - extMin.x, (extMax.y  - extMin.y)/2.0, 0);
  26.       mode->geometry().text(
  27.          insertionPnt, AcGeVector3d::kZAxis, AcGeVector3d::kXAxis, text, length, true, style);
  28.     }  
  29.     return (AcDbEntity::subWorldDraw (mode)) ;
  30. }
Код не проверял - он лишь для того, чтобы показать идею.
« Последнее редактирование: 01-08-2016, 17:38:33 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 81
  • Карма: 0
Протестировал все предложенные варианты.
Последний, где
Код - C++ [Выбрать]
  1. mode->geometry().text(insertionPnt, AcGeVector3d::kZAxis, AcGeVector3d::kXAxis, text, length, true, style);
подходит мне больше всего. Так же он немного выигрывает и в производительности.
Спасибо, Александр.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Можешь еще подумать о выносе
Код - C++ [Выбрать]
  1.   AcGiTextStyle style;
  2.   // Получаем текстовый стиль
  3.   Acad::ErrorStatus es = fromAcDbTextStyle(style, styleId);
  4.   style.loadStyleRec();
из subWorldDraw, чтобы не вызвался так часто. Скорее всего это тоже добавит производительности.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение