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

ADN Club => ObjectARX => Тема начата: ubelian от 13-11-2018, 17:11:53

Название: Плагин для работы с 3д полилиниями
Отправлено: ubelian от 13-11-2018, 17:11:53
Здравствуйте! Пишу плагин для работы с полилиниями. Принцип работы прост: при команде выскакивает диалоговое окно на MFC которое имеет поля для ввода координат для формирования 3д полилинии. С помощью переопределенного метода objectModified(const AcDbDatabase* dwg, const AcDbObject* dbObject) класса производного от  AcDbDatabaseReactor я смог поймать момент когда меняются координаты созданной моим приложением 3д полилинии. У меня появилась след. задачи:
1. Когда пользователь меняет координаты любой точки, которая составляет 3дполилинию, необходимо чтобы в моём плагине происходило тоже самое, то есть чтобы координаты менялись, желательно синхронно или после того как пользователь установит новые координаты переносимой точки.
2. Когда пользователь переносит всю 3дполилинию чтобы мой плагин отобразил новые координаты точек.
3. Когда пользователь выбирает любую созданную моим приложением 3дполилинию мой плагин должен отобразить координаты новой фигуры

Как я понимаю для решения задачи нужно как-то превратить AcDbObject* dbObject в методе objectModified в 3дполилинию, затем получить координаты точки, потом внести новые координаты в плагин. Как отследить событие когда пользователь выбирает полилинию, я не знаю. Прошу вашей помощи, буду премного благодарен.
MSVS_2012_64x использую MFC для работы с окнами
Название: Re: Плагин для работы с 3д полилиниями
Отправлено: Александр Ривилис от 13-11-2018, 17:19:22
С помощью переопределенного метода objectModified(const AcDbDatabase* dwg, const AcDbObject* dbObject) класса производного от  AcDbDatabaseReactor я смог поймать момент когда меняются координаты созданной моим приложением 3д полилинии.
В этот момент координаты уже изменённые. Поэтому чтобы словить координаты до момента их изменения нужно переопределить еще и метод AcDbDatabaseReactor::objectOpenedForModify, чтобы получить координаты до начала изменения.
Впрочем AcDb3dPolyline - это составной примитив, состоящий из вершин AcDb3dPolylineVertex. Так что есть вариант отслеживать их перемещение.
Название: Re: Плагин для работы с 3д полилиниями
Отправлено: Александр Ривилис от 13-11-2018, 17:30:40
При переносе всей 3D-полилинии:

(https://lh3.googleusercontent.com/-95NsPpEGJeQ/W-rf_iKcKtI/AAAAAAAAPQY/E4f4B72yF2wLQDwFU0BzGi0jHnyVywAmACHMYCw/s0/clipboard.png)



Название: Re: Плагин для работы с 3д полилиниями
Отправлено: Александр Ривилис от 13-11-2018, 17:32:14
А вот редактирование при помощи ручек:



ARXDBG для тестирования можно взять здесь http://adn-cis.org/forum/index.php?topic=7274.0
Название: Re: Плагин для работы с 3д полилиниями
Отправлено: Александр Ривилис от 13-11-2018, 17:39:15
3. Когда пользователь выбирает любую созданную моим приложением 3дполилинию мой плагин должен отобразить координаты новой фигуры
Тут сразу возникает куча вопросов:
1. Как отличить 3D-полилинию, нарисованную твоим приложением, от любой другой?
2. Что значит "Когда пользователь выбирает любую созданную моим приложением 3дполилинию"? Это просто выбор, когда ни одна команда AutoCAD не запущена или так же при запущенной команде? Например, запустили команду _MOVE и выбрали "твою" 3D-полилинию...
3. Если выбрано сразу несколько 3D-полилиний? Что в этом случае делать?
Если меняется набор предварительного выбора, то нужно отслеживать AcEditorReactor::pickfirstModified
Можно еще:
AcEdInputContextReactor::endSSGet
AcEdInputContextReactor::endEntsel
Название: Re: Плагин для работы с 3д полилиниями
Отправлено: ubelian от 13-11-2018, 18:00:20
Цитировать
1. Как отличить 3D-полилинию, нарисованную твоим приложением, от любой другой?
Дело в том, что плагин должен работать пока только с теми полилинияи, которые он создал. Мой код добавляет реактор для каждого созданного объекта. Вот код который рисует эту геометрию

Код - C++ [Выбрать]
  1. void createPolyline(std::vector<double> polylineDot){
  2.  
  3.         AcGePoint3dArray ptArr;
  4.         size_t polylineDotLogicalSize = polylineDot.size() / 3;
  5.         ptArr.setLogicalLength(polylineDotLogicalSize);
  6.         size_t iter = 0;
  7.         for(int i = 0; i < polylineDotLogicalSize; i++){
  8.                 ptArr[i].set(polylineDot.at(iter), polylineDot.at(iter + 1), polylineDot.at(iter + 2));
  9.                 iter = iter + 3;
  10.         }
  11.  
  12.         AcDb3dPolyline *pNewPolyLine = new AcDb3dPolyline(AcDb::k3dSimplePoly, ptArr, Adesk::kFalse);
  13.         pNewPolyLine->setColorIndex(3);
  14.         AcDbBlockTable *pBlockTable;
  15.         acdbHostApplicationServices() -> workingDatabase() -> getSymbolTable(pBlockTable, AcDb::kForRead);
  16.         AcDbBlockTableRecord *pBlockTableRecord;
  17.         //AsdkDbReactor дочка AcDbDatabaseReactor, gpDbr объект класса AsdkDbReactor
  18.         if(gpDbr == NULL){
  19.                 gpDbr = new AsdkDbReactor();
  20.         }
  21.         acdbHostApplicationServices() -> workingDatabase() -> addReactor(gpDbr);
  22.  
  23.  
  24.         pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
  25.         pBlockTable->close();
  26.  
  27.         AcDbObjectId polylineObjectId;
  28.        
  29.         pBlockTableRecord->appendNcDbEntity(polylineObjectId, pNewPolyLine);
  30.         pBlockTableRecord->close();
  31.  
  32.         pNewPolyLine->setLayer(L"0");
  33.         pNewPolyLine->close();
  34.  
  35. }
  36.  
Цитировать
2. Что значит "Когда пользователь выбирает любую созданную моим приложением 3дполилинию"? Это просто выбор, когда ни одна команда AutoCAD не запущена или так же при запущенной команде? Например, запустили команду _MOVE и выбрали "твою" 3D-полилинию...

Жмякает по ней кнопкой левой мышки, выделяя её.

Цитировать
3. Если выбрано сразу несколько 3D-полилиний? Что в этом случае делать?
А вот это хороший вопрос. Я сначала подгоню плагин под мои требования, а потом уже буду добавлять новый функционал

И ещё, как получить из AcDb3dPolyline составляющие её точки?
Название: Re: Плагин для работы с 3д полилиниями
Отправлено: Александр Ривилис от 13-11-2018, 18:09:47
ubelian,
1. Прочитай внимательно у меня в подписи как следует форматировать код у нас на форуме и соблюдай это правило!
Жмякает по ней кнопкой левой мышки, выделяя её.
Ну тогда теоретически тебе достаточно отслеживать AcEditorReactor::pickfirstModified, затем читать набор при помощи acedSSGetFirst и проверять твоя или не твоя полилиния в наборе.
И ещё, как получить из AcDb3dPolyline составляющие её точки?
Можно несколькими способами. Правильный - итератор по всем вершинам полилинии:
Код - C++ [Выбрать]
  1. AcDbObjectPointer<AcDb3dPolyline> poly3d(pObjId,AcDb::kForRead);
  2. if (poly3d.openStatus() != Acad::eOk) return;
  3. AcDbObjectIterator *pVertIter= poly3d->vertexIterator();
  4. AcDbObjectId vertexObjId;
  5. for (;!pVertIter->done();pVertIter->step()) {
  6.   vertexObjId = pVertIter->objectId();
  7.   AcDbObjectPointer<AcDb3dPolylineVertex> pVertex(vertexObjId,AcDb::kForRead);
  8.   AcGePoint3d vPts = pVertex->position();  // <-- Это координаты очередной вершины
  9. }
  10. delete pVertIter;
Название: Re: Плагин для работы с 3д полилиниями
Отправлено: Александр Ривилис от 13-11-2018, 18:42:31
appendNcDbEntity
Это что-то новенькое. Наверное, appendAcDbEntity
Название: Re: Плагин для работы с 3д полилиниями
Отправлено: ubelian от 13-11-2018, 19:10:00
Цитировать
Это что-то новенькое. Наверное, appendAcDbEntity
Дело в том что я пишу плагин для NanoCad, а он использует такое же апи что и Автокад.

Название: Re: Плагин для работы с 3д полилиниями
Отправлено: Александр Ривилис от 13-11-2018, 20:30:53
Дело в том что я пишу плагин для NanoCad, а он использует такое же апи что и Автокад.
На нашем форуме NanoCAD также как и другие клоны AutoCAD не обсуждаются!
Так что обсуждать мы будем только в контексте AutoCAD.