Параметры удалённого примитива.

Автор Тема: Параметры удалённого примитива.  (Прочитано 12344 раз)

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

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

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
В процессе изучения реакторов появилась задача отследить удаление определённых объектов (с расширенными данными) с чертежа.
Для тестирования был написан такой код:
Код - Auto/Visual Lisp [Выбрать]
  1. (defun object-reactors ( / )
  2.  (vl-load-com)
  3.  (vlr-remove-all)
  4.  (setq object-reactor (vlr-acdb-reactor nil '((:VLR-objectErased . object-erased)
  5.                                                                          (:VLR-objectUnerased . object-unerased))))
  6. )

Код - Auto/Visual Lisp [Выбрать]
  1. (defun object-erased (reactorcallback cname / )
  2. ;Если у удалённого примитива есть нужные расширенные данные, появляется сообщение:
  3.  (if (AND (assoc -3 (entget (cadr cname) '("myapp"))) (= (cdr (assoc 1000 (cdadr (assoc -3 (entget (cadr cname) '("myapp")))))) "myXdata"))
  4.       (alert "erased!")
  5.  )
  6.  (princ)
  7. )

Вскоре выяснилось, что хоть (cadr cname) и возвращает имя удалённого примитива, но (entget (cadr cname)) возвращает nil, потому что у удалённого примитива невозможно посмотреть свойства.

Какие тут есть хитрости, чтобы всё же сделать проверку свойств удалённого примитива без его восстановления и повторного удаления, на что потребуются ресурсы оперативной памяти и времени?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Параметры удалённого примитива.
« Ответ #1 : 18-10-2015, 12:06:46 »
Средствами lisp нельзя получить информацию о расширенных данных удалённого примитива. Поэтому я вижу два альтернативных способа:
1) восстанавливать примитив: (entdel en), получать информацию и удалять повторно.
ресурсы оперативной памяти не потребуются, т.к. при удалении примитива память не освобождается. Но нужно будет контролировать повторное попадание в реактор.
2) Написать функцию с использованием ObjectARX (C++) или AutoCAD .NET API (C#, VB.NET, ...) - в них можно работать с удалёнными примитивами.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
Re: Параметры удалённого примитива.
« Ответ #2 : 18-10-2015, 15:13:35 »
1) восстанавливать примитив: (entdel en), получать информацию и удалять повторно.
Бился-бился, пытаясь воплотить в жизнь это решение, а потом прочитал у Николая Полещука в книге:
Цитировать
"Объект, который стал источником события, не может быть модифицирован из функции действия, реагирующей на это событие".

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1115
  • Карма: 173
Re: Параметры удалённого примитива.
« Ответ #3 : 18-10-2015, 15:14:36 »
Я бы выполнял эти проверки перед удалением, если это возможно. Объектные реакторы стараюсь вообще не использовать - от них (судя по моему опыту) проблем больше, чем решений.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
Re: Параметры удалённого примитива.
« Ответ #4 : 18-10-2015, 15:36:33 »
Алексей Кулик, AcDb — это ведь не объектные реакторы, а ректоры базы чертежа, или ты не в этом смысле?
Я бы выполнял эти проверки перед удалением, если это возможно
Перед удалением тоже должно что-то сработать для запуска проверки. Что, если не реактор?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Параметры удалённого примитива.
« Ответ #5 : 18-10-2015, 15:52:35 »
Перед удалением тоже должно что-то сработать для запуска проверки. Что, если не реактор?
Теоретически должен сработать реактор :vlr-objectOpenedForModify
Бился-бился, пытаясь воплотить в жизнь это решение, а потом прочитал у Николая Полещука в книге:
Цитировать

    "Объект, который стал источником события, не может быть модифицирован из функции действия, реагирующей на это событие".
Отмечай в этом реакторе, а удаляй в командном реакторе (завершение команды: :vlr-commandEnded или :vlr-commandCancelled или :vlr-commandFailed)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Параметры удалённого примитива.
« Ответ #6 : 18-10-2015, 16:24:12 »
Вообще это выглядит как-то так (не проверял на ошибки в коде):
Код - Auto/Visual Lisp [Выбрать]
  1. (defun object-reactors ( / )
  2.    (vl-load-com)
  3.    (vlr-remove-all)
  4.    (setq __elist__ nil)
  5.    (setq object-reactor
  6.        (vlr-acdb-reactor nil '(
  7.           (:vlr-objectOpenedForModify . object-OpenedForModify)
  8.           (:VLR-objectErased . object-erased)
  9.        ))
  10.    )
  11. )
  12. (defun object-erased (reactorcallback cname / )
  13.    (if (and (eq (cdr (assoc -1 __elist__)) (cadr cname))
  14.             (= (cdr (assoc 1000 (cdadr (assoc -3 __elist__ '("myapp"))))) "myXdata"))
  15.       (alert "Erased my entity!!!")
  16.    )
  17. )
  18. (defun object-OpenedForModify (reactorcallback cname / )
  19.  (setq __elist__ (entget (cadr cname) '("myapp")))
  20.  (princ)
  21. )

P.S.: Проверил. Этот код не работает, т.к. и в событии OpenedForModify (entget) не работает.

P.S.S: В конце концов ты можешь в любой момент времени отобрать в список "свои примитивы" и поставить объектные реакторы на их удаление.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
Re: Параметры удалённого примитива.
« Ответ #7 : 21-10-2015, 23:45:32 »
В конце концов ты можешь в любой момент времени отобрать в список "свои примитивы" и поставить объектные реакторы на их удаление.
Можно при вставке "своих примитивов" сразу вешать на них объектные реакторы vlr-object-erased (и unerased), но при удалении вернётся только имя объекта. Свои же примитивы если и хранить списком, то списком Handle, который не меняется при переоткрытии чертежа. А при обработке события реакторы нельзя использовать (vla-get-Handle), т.к. она вернёт nil.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Параметры удалённого примитива.
« Ответ #8 : 21-10-2015, 23:52:17 »
но при удалении вернётся только имя объекта.
Вообще-то я думал, что тебя интересует сам факт удаления "твоего" примитива. Если же тебя интересуют и их свойства, то восстанавливай их в командном реакторе и получай их свойства. Ну или мигрируй на ObjectARX или .NET
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Re: Параметры удалённого примитива.
« Ответ #9 : 22-10-2015, 01:13:48 »
Можно хранить в памяти ассоциативный список пар (ename_примитива . расширенные_данные) ну и соответственно следить за поддержанием его в актуальном состоянии - такой метод кстати в некоторых случаях является единственным и в .Net (и по моему и в ARX) - например при перемещении ручек примитива - так-же возвращается не "настоящий" указатель, а его копия.

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

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
Re: Параметры удалённого примитива.
« Ответ #10 : 22-10-2015, 01:20:34 »
Вообще-то я думал, что тебя интересует сам факт удаления "твоего" примитива.
Так и есть. Но помимо самого факта удаления некоего примитива с расширенными данными важно понять, какой из них был удалён. А при удалении примитива от реактора мы получаем максимум его имя, а не указатель, что однозначно могло бы указать на примитив для осуществления неких внеших действий (например, удаление ссылки на объект во внешнем текстовом файле по указателю).
Ну или мигрируй на ObjectARX или .NET
В .NET есть возможность узнать свойства (в т.ч. указатель на объект, наличие расширенных данных) удалённого объекта и аналоги лисповских реакторов для этого?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Параметры удалённого примитива.
« Ответ #11 : 22-10-2015, 07:38:27 »
В .NET есть возможность узнать свойства (в т.ч. указатель на объект, наличие расширенных данных) удалённого объекта и аналоги лисповских реакторов для этого?
Если ты имеешь в виду метку (handle) примитива, то да. Реакторов в нём поболее чем в лиспе. Самое большое количество возможностей в ObjectARX.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение