Сообщество программистов Autodesk в СНГ

ADN Club => ObjectARX => Тема начата: knightrocker от 17-05-2018, 13:03:35

Название: Как сдвинуть нарисованный круг
Отправлено: knightrocker от 17-05-2018, 13:03:35
Я создал объект круг с использованием AcDbCircle добавил его на чертёж используя appendAcDbEntity, он отобразился. Как сдвинуть имеющийся круг по оси x на 10 и по оси y на 20. Не перерисовывая круг по новой, а именно осуществляя сдвиг уже нарисованного объекта ?
Название: Re: Как сдвинуть нарисованный круг
Отправлено: Александр Ривилис от 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.  
Название: Re: Как сдвинуть нарисованный круг
Отправлено: Debalance от 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));
Название: Re: Как сдвинуть нарисованный круг
Отправлено: knightrocker от 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.  
Название: Re: Как сдвинуть нарисованный круг
Отправлено: Александр Ривилис от 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() должен быть выполнен в любом случае.
Название: Re: Как сдвинуть нарисованный круг
Отправлено: Debalance от 22-05-2018, 13:33:50
... открыть (не создать, а открыть)
Это азбука (http://help.autodesk.com/view/OARX/2018/RUS/?guid=GUID-3D97B315-EA1E-42B4-AF75-635B9C3B8D9E)...
Название: Re: Как сдвинуть нарисованный круг
Отправлено: Александр Ривилис от 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.         }
А вот это вообще какой-то страшный бред. Сколько в него не всматривался так и не понял.
Название: Re: Как сдвинуть нарисованный круг
Отправлено: Debalance от 22-05-2018, 13:57:40
А вот это вообще какой-то страшный бред.
Вот это:
Код - C++ [Выбрать]
  1. if (Blok->isWriteEnabled() == Adesk::kFalse)
обычно идёт в связке с:
Код - C++ [Выбрать]
  1. Blok->upgradeOpen();
Но тогда надо было хотя бы:
Код - C++ [Выбрать]
  1. Blok = getModelSpace(AcDb::kForRead);
Название: Re: Как сдвинуть нарисованный круг
Отправлено: Александр Ривилис от 22-05-2018, 14:35:36
А вот это вообще какой-то страшный бред.
Вот это:
Код - C++ [Выбрать]
  1. if (Blok->isWriteEnabled() == Adesk::kFalse)
обычно идёт в связке с:
Код - C++ [Выбрать]
  1. Blok->upgradeOpen();
Но тогда надо было хотя бы:
Код - C++ [Выбрать]
  1. Blok = getModelSpace(AcDb::kForRead);

Я про повторное открытие уже открытого AcDbBlockTableRecord.
Название: Re: Как сдвинуть нарисованный круг
Отправлено: Debalance от 22-05-2018, 14:48:35
Я про повторное открытие уже открытого AcDbBlockTableRecord.
Да, это определённо лажа. Видимо knightrocker вставил сей кусочек кода из какого-то примера, так сказать, по инерции, а подправить забыл. Бывает...