Как сдвинуть нарисованный круг

Автор Тема: Как сдвинуть нарисованный круг  (Прочитано 4244 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Я создал объект круг с использованием AcDbCircle добавил его на чертёж используя appendAcDbEntity, он отобразился. Как сдвинуть имеющийся круг по оси x на 10 и по оси y на 20. Не перерисовывая круг по новой, а именно осуществляя сдвиг уже нарисованного объекта ?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как сдвинуть нарисованный круг
« Ответ #1 : 17-05-2018, 13:27:02 »
Я создал объект круг с использованием AcDbCircle добавил его на чертёж используя appendAcDbEntity, он отобразился. Как сдвинуть имеющийся круг по оси x на 10 и по оси y на 20. Не перерисовывая круг по новой, а именно осуществляя сдвиг уже нарисованного объекта ?
Код - C++ [Выбрать]
  1.    
  2. AcDbCircle *pCircle = NULL;
  3. // ... Где-то pCircle инициализируется
  4. AcGeMatrix3d mat;
  5. mat.setToTranslation(AcGeVector3d(10,20,0));
  6. pCircle->transformBy(mat);
  7.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Debalance

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: Как сдвинуть нарисованный круг
« Ответ #2 : 18-05-2018, 14:53:42 »
А может так:

Код - C++ [Выбрать]
  1. AcDbCircle *pCircle = NULL;
  2. // ... Где-то pCircle инициализируется и уже pCircle != NULL
  3. // А затем:
  4. pCircle->setCenter(pCircle->center() + AcGeVector3d(10.0, 20.0, 0.0));
« Последнее редактирование: 18-05-2018, 21:15:50 от Debalance »

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Re: Как сдвинуть нарисованный круг
« Ответ #3 : 22-05-2018, 13:21:08 »
Благодарю Александр Ривилис и Debalance за ответы.
Подскажите пожалуйста ещё следующее:
Как сдвинуть уже добавленный объект после его закрытия ?
Хочется передвинуть круг уже после закрытия, повторно "открыв" этот объект / сущность.

Попытался вот так, но mat.setToTranslation вылетает с исключением.

Код - C++ [Выбрать]
  1. AcDbBlockTableRecord* getModelSpace(AcDb::OpenMode mode)
  2. {
  3.         AcDbBlockTableRecord* Blok = NULL;
  4.         AcDbBlockTable *pBlockTable;
  5.  
  6.         Acad::ErrorStatus es;
  7.  
  8.         AcApDocument* pDoc = acDocManager->curDocument();
  9.         es = acDocManager->lockDocument(pDoc);
  10.         if (es != Acad::eOk)
  11.                 ads_alert(_T("Failed to lock the document!"));
  12.  
  13.         AcDbDatabase* pDb = pDoc->database();
  14.  
  15.         es = pDb->getBlockTable(pBlockTable, AcDb::kForRead);
  16.         if (es != Acad::eOk)
  17.         {
  18.                 ads_alert(_T("Failed to get block table!"));
  19.                 return NULL;
  20.         }
  21.  
  22.         if (!pDb) return NULL;
  23.  
  24.         AcDbBlockTable* pTbl = NULL;
  25.         es = pDb->getBlockTable(pTbl, AcDb::kForRead);
  26.         if (es != Acad::eOk) return NULL;
  27.         es = pTbl->getAt(ACDB_MODEL_SPACE, Blok, mode);
  28.         pTbl->close();
  29.         if (es != Acad::eOk) return NULL;
  30.  
  31.         return Blok;
  32. }
  33.  
  34. Acad::ErrorStatus MoveCreatedCircle()
  35. {
  36.         AcDbBlockTableRecord* Blok = NULL;
  37.         AcDbObjectId id;
  38.         Acad::ErrorStatus es;
  39.  
  40.         AcGePoint3d cntr(0, 0, 0);
  41.         ads_real r = 3;
  42.         AcGeVector3d ptMove(20, 20, 0);
  43.  
  44.         AcDbCircle* pCirEnt = new AcDbCircle();
  45.         pCirEnt->setCenter(cntr);
  46.         pCirEnt->setRadius(r);
  47.  
  48.         if (!pCirEnt) return Acad::eNullEntityPointer;
  49.  
  50.         Acad::ErrorStatus es;
  51.         if (!Blok)
  52.         {
  53.                 Blok = getModelSpace(AcDb::kForWrite);
  54.                 if (!Blok) return Acad::eInvalidOwnerObject;
  55.         }
  56.         if (Blok->isWriteEnabled() == Adesk::kFalse)
  57.         {
  58.                 AcDbObject* pObj = NULL;
  59.                 es = acdbOpenObject(pObj, Blok->objectId(), AcDb::kForWrite);
  60.                 Blok = AcDbBlockTableRecord::cast(pObj);
  61.         }
  62.         //if ((es = Blok->appendAcDbEntity(pCirEnt)) != Acad::eOk)
  63.         Blok->close();
  64.  
  65.         id = pCirEnt->objectId();
  66.  
  67.         es = pCirEnt->close();
  68.  
  69.         // Хочется передвинуть круг уже после закрытия
  70.         // повторно "открыв" этот объект / сущность
  71.  
  72.         //open the selected entity
  73.         AcDbEntity *pEntity2 = NULL;
  74.         if (acdbOpenAcDbEntity(pEntity2, id, AcDb::kForRead) != Acad::eOk)
  75.                 return es;
  76.  
  77.         //AcDbPolyline *pPline = AcDbPolyline::cast(pEntity2);
  78.         AcDbCircle *pSameCirc = AcDbCircle::cast(pEntity2);
  79.         if (pSameCirc == NULL)
  80.                 return es;
  81.  
  82.         AcGeMatrix3d mat;
  83.         mat.setToTranslation(AcGeVector3d(ptMove[X], ptMove[Y], ptMove[Z]));
  84.         pSameCirc->transformBy(mat);
  85.  
  86.         es = pSameCirc->close();
  87. }
  88.  

Отмечено как Решение knightrocker 10-06-2018, 14:07:22

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как сдвинуть нарисованный круг
« Ответ #4 : 22-05-2018, 13:28:40 »
knightrocker
Для того, чтобы модифицировать (в данном конкретном случае передвинуть) примитив - его нужно открыть (не создать, а открыть). Открыть его можно только зная его id (AcDbObjectId) или handle (AcDbHandle) и никак иначе.
Чтобы его можно было модифицировать открывать нужно AcDb::kForWrite, а не AcDb::kForRead
Вот это лишнее:
Код - C++ [Выбрать]
  1. AcDbCircle *pSameCirc = AcDbCircle::cast(pEntity2);
так как метод transformBy есть и у AcDbEntity, а не только у AcDbCircle.
Так тоже делать нельзя:
Код - C++ [Выбрать]
  1.  if (pSameCirc == NULL)
  2.                 return es;
Метод close() должен быть выполнен в любом случае.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Debalance

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: Как сдвинуть нарисованный круг
« Ответ #5 : 22-05-2018, 13:33:50 »
... открыть (не создать, а открыть)
Это азбука...

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как сдвинуть нарисованный круг
« Ответ #6 : 22-05-2018, 13:39:56 »
       
Код - C++ [Выбрать]
  1. if (Blok->isWriteEnabled() == Adesk::kFalse)
  2.         {
  3.                 AcDbObject* pObj = NULL;
  4.                 es = acdbOpenObject(pObj, Blok->objectId(), AcDb::kForWrite);
  5.                 Blok = AcDbBlockTableRecord::cast(pObj);
  6.         }
А вот это вообще какой-то страшный бред. Сколько в него не всматривался так и не понял.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Debalance

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: Как сдвинуть нарисованный круг
« Ответ #7 : 22-05-2018, 13:57:40 »
А вот это вообще какой-то страшный бред.
Вот это:
Код - C++ [Выбрать]
  1. if (Blok->isWriteEnabled() == Adesk::kFalse)
обычно идёт в связке с:
Код - C++ [Выбрать]
  1. Blok->upgradeOpen();
Но тогда надо было хотя бы:
Код - C++ [Выбрать]
  1. Blok = getModelSpace(AcDb::kForRead);

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как сдвинуть нарисованный круг
« Ответ #8 : 22-05-2018, 14:35:36 »
А вот это вообще какой-то страшный бред.
Вот это:
Код - C++ [Выбрать]
  1. if (Blok->isWriteEnabled() == Adesk::kFalse)
обычно идёт в связке с:
Код - C++ [Выбрать]
  1. Blok->upgradeOpen();
Но тогда надо было хотя бы:
Код - C++ [Выбрать]
  1. Blok = getModelSpace(AcDb::kForRead);

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

Оффлайн Debalance

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: Как сдвинуть нарисованный круг
« Ответ #9 : 22-05-2018, 14:48:35 »
Я про повторное открытие уже открытого AcDbBlockTableRecord.
Да, это определённо лажа. Видимо knightrocker вставил сей кусочек кода из какого-то примера, так сказать, по инерции, а подправить забыл. Бывает...