Изменение поворота текста

Автор Тема: Изменение поворота текста  (Прочитано 9109 раз)

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

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

  • ADN OPEN
  • Сообщений: 12
  • Карма: 0
Добрый день, решил попробовать себя в разработке простейших функций для autocad. Занимаюсь этим около недели, прошу строго не судить. Возникла такая проблема: есть несколько тысяч объектов однострочного текста в чертеже. Все объекты нужно повернуть на 180 градусов (как при использовании поля свойств "поворот"), чтобы каждый текст поворачивался относительно точки вставки. Также хотелось бы добавить какой-нибудь префикс/суффикс к каждому текстовому объекту. Я пытаюсь использовать класс AcDbText и методы setrotation и settextstring, но ничего не получается. Текст не поворачивается, а значение содержимого не меняется. Использую такой код.
Код - C++ [Выбрать]
  1. static void MyGroupMyPickFirst () {
  2.                 ads_name result ;
  3.                 resbuf *prb = acutBuildList(RTDXF0, L"TEXT", RTNONE);
  4.                 int iRet = acedSSGet (ACRX_T("_I"), NULL, NULL, prb, result) ;
  5.                 if ( iRet == RTNORM )
  6.                 {
  7.                         AcTransaction* pTrans = acdbTransactionManager->startTransaction();
  8.                         if (NULL == pTrans)
  9.                         {
  10.                                 return;
  11.                         }
  12.  
  13.                         acutRelRb(prb);
  14.                        
  15.                         AcDbObjectIdArray ids;
  16.                         AcDbText *txtEnt = new AcDbText();
  17.                         AcDbObjectId id = 0;
  18.                         AcDbText* pExistingText = NULL;
  19.                         double rad, myrad, radexsist;
  20.                         int res;
  21.                         ACHAR* mytext;
  22.                         ACHAR pref[10];
  23.                        
  24.                         if (ObjectIdArrayFromSelSet(result, ids) != Acad::eOk)
  25.                                 acutPrintf(L"\n Нет выбранных объектов.");
  26.  
  27.                         int i = ids.length() - 1;
  28.                         //Запрос угла поворота текста
  29.                         res = acedGetAngle(NULL, L"\n Введите угол поворота текста: ", &rad);
  30.                         if (res == RTNONE) rad = 0.0;
  31.                         else if (res != RTNORM) return;
  32.                        
  33.                         //Запрос префикса
  34.                         res = acedGetString(0, L"\n Введите префикс для текста: ", pref);
  35.                         if (res == RTNONE) rad = 0.0;
  36.                         else if (res != RTNORM) return;
  37.  
  38.                         while (i >= 0)
  39.                         {
  40.                                 id = ids[i];
  41.                                 Acad::ErrorStatus es = acdbTransactionManager->getObject((AcDbObject*&)pExistingText, id, AcDb::kForWrite);
  42.                                 if (!eOkVerify(es))
  43.                                 {
  44.                                         acdbTransactionManager->abortTransaction();
  45.                                         acedPrompt(_T("\nЭто не текст"));
  46.                                         return;
  47.                                 }
  48.                                
  49.                                 //mytext = strcat (pref, pExistingText->textString());
  50.                                 es = pExistingText->setTextString(mytext);
  51.                                 if (es != Acad::eOk)
  52.                                 {
  53.                                         acutPrintf(L"\n-- Ошибка при изменении строки текста - %s", Acad::ErrorStatus());
  54.                                         return;
  55.                                 }
  56.  
  57.                                 myrad = pExistingText->rotation()+rad;
  58.                                 radexsist = pExistingText->rotation();
  59.                                 acutPrintf(L"\n-- Новый угол поворота текста - %.6q0", myrad);
  60.  
  61.                                 es = pExistingText->setRotation(myrad);
  62.                                 if (es != Acad::eOk)
  63.                                 {
  64.                                         acutPrintf(L"\n-- Ошибка при повороте текста - %s", Acad::ErrorStatus());
  65.                                         return;
  66.                                 }
  67.  
  68.                                 acutPrintf(L"\n-- Предыдущий угол поворота текста - %.6q0", radexsist);
  69.                                 i--;
  70.                         }
  71.                         acdbTransactionManager->abortTransaction();
  72.                 }
  73.                 else
  74.                 {
  75.                         // There are no selected entities
  76.                         // Put your command code here
  77.                 }
  78.         }
  79.  
  80.         static Acad::ErrorStatus ObjectIdArrayFromSelSet(ads_name sset, AcDbObjectIdArray &ids) {
  81.                 Acad::ErrorStatus es = Acad::eOk;
  82.                 long nset = -1;
  83.                 if (acedSSLength(sset, &nset) != RTNORM) return Acad::eAmbiguousInput;
  84.                 ids.setLogicalLength(nset);
  85.                 ads_name en;
  86.                 AcDbObjectId id;
  87.                 for (long i = 0; i < nset; i++) {
  88.                         if (acedSSName(sset, i, en) == RTNORM) {
  89.                                 if ((es = acdbGetObjectId(id, en)) != Acad::eOk) return es;
  90.                                 ids[i] = id;
  91.                         }
  92.                 }
  93.                 return Acad::eOk;
  94.         }
  95.  
Строку "mytext = pref + pExistingText->textString();" закомментировал, потому что пока не разобрался как объединить эти значения вместе. Если подскажете как это сделать, буду очень благодарен.
Может я не в том направлении решил двигаться? Может мне нужно работать с текстовыми объектами как AcDbEntity и поворачивать как при использовании автокадовской операции "поворот"? Подскажите, пожалуйста.


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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменение поворота текста
« Ответ #1 : 13-12-2015, 01:08:35 »
Приветствую на форуме!
Я пытаюсь использовать класс AcDbText и методы setrotation и settextstring, но ничего не получается. Текст не поворачивается, а значение содержимого не меняется.
Ну это как бы очевидно. Разберись с тем как ты используешь транзакции. В одном месте ты её создаёшь и потом вызываешь acdbTransactionManager->abortTransaction(); вместо того, чтобы вызвать acdbTransactionManager->endTransaction();
Да и вообще мне не ясно зачем ты связался с транзакциями. Всё-тоже самое можно было сделать значительно проще и без них.
Далее непонятно что ты имеешь в виду под поворотом на 180 градусов. Это поворот относительно текущего поворота каждого из текстов? Тогда логичнее использовать метод transformBy(), создав матрицу поворота относительно базовой точки на угол 180 градусов.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Gurikin 13-12-2015, 02:55:24

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменение поворота текста
« Ответ #2 : 13-12-2015, 02:37:15 »
Сравни этот код со своим:
Код - C++ [Выбрать]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.cpp
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #define _USE_MATH_DEFINES
  6. #include <math.h>
  7.  
  8. #include "resource.h"
  9.  
  10. static Acad::ErrorStatus ObjectIdArrayFromSelSet(ads_name sset, AcDbObjectIdArray &ids) {
  11.   Acad::ErrorStatus es = Acad::eOk;
  12.   long nset = -1;
  13.   if (acedSSLength(sset, &nset) != RTNORM) return Acad::eAmbiguousInput;
  14.   ids.setLogicalLength(nset);
  15.   ads_name en;
  16.   AcDbObjectId id;
  17.   for (long i = 0; i < nset; i++) {
  18.     if (acedSSName(sset, i, en) == RTNORM) {
  19.       if ((es = acdbGetObjectId(id, en)) != Acad::eOk) return es;
  20.       ids[i] = id;
  21.     }
  22.   }
  23.   return Acad::eOk;
  24. }
  25.  
  26. //-----------------------------------------------------------------------------
  27. //----- ObjectARX EntryPoint
  28. class CTextRotateApp : public AcRxArxApp {
  29. public:
  30.   CTextRotateApp () : AcRxArxApp () {}
  31.   virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
  32.     AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
  33.     return (retCode) ;
  34.   }
  35.   virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
  36.     AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
  37.     return (retCode) ;
  38.   }
  39.  
  40.   virtual void RegisterServerComponents () {    }
  41.  
  42.   static void RivilisTransformText () {
  43.     ads_name result ;
  44.     resbuf *filter = acutBuildList(RTDXF0, L"TEXT", RTNONE);
  45.     int rc = acedSSGet (NULL, NULL, NULL, filter, result) ;
  46.     acutRelRb(filter);
  47.     if (rc == RTCAN) return;
  48.     if (rc != RTNORM) {
  49.       acutPrintf(_T("\nПримитивы TEXT не найдены."));
  50.       return;
  51.     }
  52.     AcDbObjectIdArray ids;
  53.     ObjectIdArrayFromSelSet(result, ids);
  54.     double ang = 0;
  55.     acedGetAngle(NULL,_T("\nУкажите угол, на который поворочивается каждый текст: "), &ang);
  56.     if (rc == RTCAN) return;
  57.     ACHAR prefix[256] = _T(""),
  58.       suffix[256] = _T("");
  59.     if (acedGetString(TRUE,_T("\nУкажите префикс: "), prefix) == RTCAN) return;
  60.     if (acedGetString(TRUE,_T("\nУкажите суффикс: "), suffix) == RTCAN) return;
  61.  
  62.     for (int i = 0; i < ids.length(); i++)
  63.     {
  64.       AcDbObjectPointer<AcDbText> pText(ids[i], AcDb::kForWrite);
  65.       if (pText.openStatus() == Acad::eOk) {
  66.         pText->setTextString(AcString(prefix) + pText->textString() + AcString(suffix));
  67.         pText->setRotation(pText->rotation() + ang); // Поворачиваем на заданный угол.
  68.         // pText->setRotation(ang); // Устанавливаем угол поворота
  69.       }
  70.     }
  71.   }
  72.  
  73. } ;
  74.  
  75. //-----------------------------------------------------------------------------
  76. IMPLEMENT_ARX_ENTRYPOINT(CTextRotateApp)
  77.  
  78. ACED_ARXCOMMAND_ENTRY_AUTO(CTextRotateApp, Rivilis, TransformText, TFT, ACRX_CMD_MODAL | ACRX_CMD_USEPICKSET, NULL)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 12
  • Карма: 0
Re: Изменение поворота текста
« Ответ #3 : 13-12-2015, 02:52:05 »
Спасибо огромное за помощь. С транзакцией код поправил - стало работать. Ваш пример просмотрел, без транзакций код более прозрачен и прост в понимании. К сожалению не знал про класс AcDbObjectPointer. Ещё раз благодарю за помощь.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменение поворота текста
« Ответ #4 : 13-12-2015, 02:54:11 »
Ещё раз благодарю за помощь
Пожалуйста. Обращайся :)
P.S.: Прочитай у меня в подписи о кнопке Решение.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение