AutoLISP: Работа с реакторами
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > AutoLISP: Работа с реакторами

AutoLISP: Работа с реакторами

Ответ
Поиск в этой теме
Непрочитано 28.11.2008, 12:43 #1
AutoLISP: Работа с реакторами
Supermax
 
Руководитель фирмы
 
Москва
Регистрация: 28.03.2007
Сообщений: 1,831

В этой теме я подробно изложу все тонкости работы с реакторами.

В замечательной книге Н.Н. Полещука "AutoLISP и Visual Lisp в среде AutoCAD" есть целая глава, посвященная этому, очень сильному инструменту, но она писалась, по всей видимости, в последнюю очередь и сил на подробное освещение всех нюансов, видимо не хватило.
Так заполним же этот пробел.

Я не буду повторять написанное в этой книге! Я буду давать данные, опираясь на предположение, что вы имеете эту книгу и читали эту главу.

И так:

Есть временные реакторы и постоянные. Временные работают только в текущем сеансе редактирования рисунка, постоянные - встраиваются в рисунок и срабатывают везде, где этот рисунок открыт.

НО!

Без подгруженных функций, которые эти реакторы должны запускать дело не пойдет, а вот их-то и проблема подгрузить.

Если речь идет об универсальных функциях - нет проблем. Добавляем их в файл acaddoc.lsp и все. Они будут подгружаться во все открываемые документы. Но разве это надо? Правильно, вот и я подумал - не надо. Надо, чтобы из той директории, в которой лежит файл с рисунком, запускался (в случае ниличия) одноименный файл *.lsp с функциями, нужными только этому рисунку (раз в него реакторы понатыканы).

Вот я и сделал такой файл acaddoc.lsp, который не содержит функций, но который при каждом открытии рисунка проверяет, а нет ли в этой же директории такого же лисп-файла и если есть - подгружает все, что в нем в этот рисунок.

Получилось что-то типа проекта, состоящего из файла DWG и прилагаемых к нему файлов.

Вот код файла acaddoc.lsp.
Код:
[Выделить все]
(vl-load-com)
(setq actdoc (vla-get-ActiveDocument (vlax-get-acad-object)))
(setq win-tit (vla-get-WindowTitle actdoc))
(if (vl-file-directory-p (vl-filename-directory win-tit))
 (progn
  (setq win-tit 
   (vl-list->string 
    (reverse 
     (append 
      '(112 115 108) 
       (cdddr 
        (reverse 
         (vl-string->list win-tit)
        )
       )
      )
     )
    )
   )
  (if (findfile win-tit) 
   (load win-tit)
  )
 )
)
(setq win-tit nil)
Тут можно и сообщение добавить, о том, что функции введены и если такой файл есть, то добавить этот текст в него.
Просмотров: 12699
 
Непрочитано 28.11.2008, 13:04
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Ты сам-то понял, чего хотел?
Реакторы сами по себе достаточно опасная штука. Вдобавок в каждом конкретном случае (имею в виду прежде всего вертикальные решения) надо проверять корректность работы этого реактора. Я уже не говорю о "навесках" типа СПДС / MechaniCS etc,- там свои тараканы могут встречаться.
Постоянные реакторы навесить можно, и ты прав в том плане, что
Цитата:
Без подгруженных функций, которые эти реакторы (постоянные - дополнение мое) должны запускать дело не пойдет<...>
Мало того что не пойдет, еще и огребешь по полной, если реактор постоянный и навешен на объект.
А вот что "проблема их загрузить" - извини, это тебе просто лень заниматься. Прописывается код с реакторами в автозагрузку и работай как хочешь.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 28.11.2008, 13:12
#3
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


В автозагрузку все не пропишешь, и надо ли оно? Вот есть у меня файл с прикрученным реактором, так что, из-за него во все рисунки загружать нужные только ему лиспы?
И если нет в рисунке таких функций - просто пишет - нет такой функции. Что тут огребать? На нет и суда нет.

Потом, я уже просек, что надо после срабатывания реактора, ставить в очередь выполнение нужных тебе функций и сразу из него сваливать. То есть функции начнут выполняться только после завершения обработки события и окончании работы реактора.

Код сейчас подгоню.
Supermax вне форума  
 
Непрочитано 28.11.2008, 13:25
#4
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Извини, но то, что ты говоришь - фигня чистой воды. Тебе никто не может помешать запускать свои функции как в момент срабатывания реактора, так и в момент выхода из него.
А то, что "функция отсутствует" - это до поры до времени. Когда файл рухнет или аудит твои объекты порушит - вот тогда ты поймешь, о чем я говорил. Я такое словил на 2005 ADT, с тех пор либо гарантированная загрузка реакторов, либо без постоянных. Второе предпочтительнее.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 28.11.2008, 14:33
#5
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Не фигня! Стр. 788 раздел 9.8
1. 3-е ограничение. Цитирую:

Цитата:
В функциях действия нельзя использовать такие интерактивные функции, как getkword, getpoint, entsel и т.д. Кроме того, запрещается в функциях действия применять функцию command.
4-е ограничение
Цитата:
Нельзя вызывать диалоговые окна во время обработки событий. Функции, работающие с диалоговыми окнами, относятся к интерактивным функциям и поэтому будут конфликтовать с работой реакторов.
5-е ограничение
Цитата:
Объект, который стал источником события, не может быть модифицирован из функции действия, реагирующей на это событие.

Так вот, мне надо нарушить все эти три правила.

Мне надо, при переключении в динамическом блоке значения свойства "Настройка блока" со значения "Блок настроен" на значение "Настроить", чтобы сработал реактор, проверил значение свойства и если оно переключено - запустил программу перестройки блока.

Проверить можно напрямую из функции действия, а вот все остальное - только дождавшись окончания работы реактора. И КАК я уже знаю.

Сейчас будет код. погоди.
Supermax вне форума  
 
Автор темы   Непрочитано 28.11.2008, 15:46
#6
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Создаем реактор объекта:
Код:
[Выделить все]
; Указываем на нужный нам объект:
(setq obj (vlax-ename->vla-object (car (entsel))))
;Устанавливаем на него реактор модификации 
(setq reactor1 (vlr-object-reactor (list obj) nil (list '(:VLR-modified . vlr-sdd22))))
;Делаем его постоянным
(vlr-pers reactor1) ;Пардон, тут ошибка была
Для очистки рисунка от реакторов запускаем
Код:
[Выделить все]
(vlr-remove-all)
Если теперь пошевелить объект, то будет срабатывать реактор. Но нужна функция vlr-sdd22 хоть в точечной паре она указана без аргументов, ее надо делать с тремя аргументами.

Вариант 1 (нельзя так делать!)
Код:
[Выделить все]
(defun VLR-SDD22 (a-object b-vlr-object c-data / ) 
  (vla-SendCommand 
    (vla-get-ActiveDocument (vlax-get-acad-object)) 
    "(alert \"Привет!\") ")
(alert "Пока еще нет привета")
)
Обращаю внимание на то, что "Пока еще нет привета" стоит в лиспе после "Привет", а срабатывает раньше его. Почему? - Да потому, что vla-SendCommand передает данные в ком. строку как бы из вне, а из вне все выстраивается в очередь. Пока реактор не отработает свое, он будет занимать Автокад, а как только закончит это делать - вуаля, все, что в очереди будет выполнено.

Второй вариант: (так тоже нельзя делать!)
Код:
[Выделить все]
;Функция запускаемая по окончании действия реактора
(defun lisp_Onobj () (alert "Привет"))
;Функция действия самого реактора
(defun VLR-SDD22 (a-object b-vlr-object c-data / ) 
(setq ScriptControl (vlax-get-or-create-object "MSScriptControl.ScriptControl"))
(vlax-put-property ScriptControl "Language" "VBScript")
(vlax-invoke-method ScriptControl "AddCode" "
  Set AutoCAD = GetObject(, \"AutoCAD.Application\")
  Set ActiveDocument = AutoCAD.ActiveDocument
  ActiveDocument.SendCommand \"(lisp_Onobj) \"
")
)
Аналогичная история, только в скрипте можно еще очень многое сделать недоступное в Автокаде. Точно так же посыл в командную строку выстраивается в очередь и обрабатывается только после окончания работы самого реактора.

Третий вариант: (Правильный)

Код:
[Выделить все]
;Функция запускаемая по окончании действия реактора
(defun lisp_Onobj () 
;освобождаем объект Script
(vl-catch-all-apply '(lambda () (vlax-release-object script)))
(alert "Привет"))
;Функция действия самого реактора
(defun VLR-SDD22 (a-object b-vlr-object c-data / ) 
;Сохраняем указатель на объект - блок "линия
 (setq stat-object a-object)
;Сохраняем указатель на объект - реактор
 (setq stat-vlr-object b-vlr-object)
;записываем имя временного файла
(setq Fdcl "Sel555.vbs")
;Создаем путь к временному файлу
(setq Fdcl (strcat (VL-FILENAME-DIRECTORY(vl-filename-mktemp Fdcl)) "\\" Fdcl))   
(vl-file-delete Fdcl)  ;Если есть такой файл, то его убить, поскольку он каждый раз создается с 0.

(setq dsl0055 (open Fdcl "w")) ;Открываем и заполняем файл Sel555.vbs 
(write-line "Set AutoCAD = GetObject(, \"AutoCAD.Application\")" dsl0055)
(write-line "Set ActiveDocument = AutoCAD.ActiveDocument" dsl0055)
(write-line "WScript.Sleep 10" dsl0055)
(write-line "ActiveDocument.SendCommand \"(lisp_Onobj) \"" dsl0055)
(close dsl0055)
;Запускаем скрипт.
(setq script (DwgRu-WScript-Exec Fdcl ""))

;Сваливаем из реактора
)

Последний раз редактировалось Supermax, 30.11.2008 в 14:59.
Supermax вне форума  
 
Автор темы   Непрочитано 28.11.2008, 15:54
#7
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Таким макаром работают все функции, в состав которых входит и command, и entget, и DCL панели и прочее. Можно этот же объект удалять из списка объектов на обработку реактором и наоборот, добавлять. Я уж молчу, что его можно вообще весь переделать и он останется привязан к реактору (разумеется его сначала удаляют из списка, переделывают, и опять добавляют к списку).
Supermax вне форума  
 
Непрочитано 28.11.2008, 16:15
#8
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


1. Устойчивость такого реактора находится под очень большим вопросом.
2. Попытка навесить такое на CustomObject (объект СПДС / MechaniCS / ADT) при условии подгруженного ObjectEnabler'a или соответствующего arx может развалить AutoCAD
3. То же, что и 2, но без подгруженного OE или arx может завалить acad.exe при открытии файла с условием подгрузки сначала arx, а потом соответствующего реактора. Иногда срабатывает и при обратном порядке загрузки.*
4. Если через SendCommand в реакторе, привязанном к объекту, ты (случайно или нет - дело десятое) пошлешь команду на изменение этого же объекта (удаление тоже, по-моему, считается изменением), у тебя пойдет бесконечный цикл. Вдобавок рано или поздно получишь либо переполнение стека, либо ошибку 0x000005 (ну или сколько там нулей). Выход, как правило, только один - перезапуск acad.exe.
---
Резюме: не иди в лоб, ищи обходные пути.
---
Добавлено:
* порядок загрузки лично мне отрегулировать не удавалось ни разу.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 28.11.2008, 16:40
#9
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Ай, ай, ай! Опять ты не понял.

Вышел я уже из реактора! ВЫШЕЛ!

Пока был в функции действия, понавтыкал в очередь запуск других функций, но не выполнял их, пока не выйду, а когда вышел, они сами запустились. Я же указал прямо, на тот факт, что выполняется все, вплоть до самого конца функции действия, а то, что послано через vla-SendCommand, выполнится только когда реакция закончится. Это все равно, что просто запустить функцию не трогая объекты.

Весь реактор из двух строчек, и нет в нем никаких действий по отношению к объекту, который вызвал эту реакцию реактора.
Но, вот когда обработка события завершена и реактор опять переходит в спящий режим, начинают срабатывать лиспы, которые не могли пробиться к ком. строке, из-за работы реактора.
Ну что может натворить функция, чье имя торчит в очереди? типа "(lisp_Onobj) ".
Supermax вне форума  
 
Непрочитано 28.11.2008, 16:44
#10
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Вызов ком.строки из-под реактора даже через SendCommand лично у меня несколько раз убивал acad. Я (надеюсь) не дурнее паровоза и вызывал SendCommand из функции окончания реактора. Поэтому я и сказал насчет устойчивости.
Теперь навесь на любой объект свой реактор изменения объекта и выполни (в конце, естественно) любую команду, затрагивающую этот объект.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 28.11.2008, 16:49
#11
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


По поводу бесконечного цикла.
Есть много способов его устроить, но разве нам это надо?
Я написал, а ты не прочитал, что
Цитата:
... (разумеется его сначала удаляют из списка, переделывают, и опять добавляют к списку).
Естественно, что перед модификацией надо удалить из этого реактора указатель на объект, к которому он привязан, а после модификации, добавить указатель на этот объект к этому реактору (даже если он стал другим).
Supermax вне форума  
 
Непрочитано 28.11.2008, 17:00
#12
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Замечательно! Представь себе ситуацию:
1. Объект с хендлом "1234"
2. На его изменение "повешен" реактор с SendCommand
3. После изменения объекта срабатывает реактор, затрагивающий этот объект.
Каковы будут твои действия для решения проблемы п.3? Ведь потом надо обратно реактор повесить...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 28.11.2008, 17:30
#13
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Ща, сварганю.
Есть объект с повешанным на него реактором. К примеру - динамический блок "Линия". Надо при попытке изменить длинну линии, устанавливать ее длинну в нужное значение. Сойдет такой пример?
Supermax вне форума  
 
Автор темы   Непрочитано 28.11.2008, 20:06
#14
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Даю файл DWG с динамическим блоком "Линия" и установленным на нем реактором, а также файл с двумя функциями к нему.

Код:
[Выделить все]
(vl-load-com)
;============= Функция редактирования динамического блока "Линия" =================
(defun modline (/ S_Document S_ModelSpace point-temp)
;Получаем указатели на активный документ и пространство модели
  (setq S_Document (vla-get-ActiveDocument (vlax-get-acad-object)))
  (setq S_ModelSpace (vla-get-ModelSpace S_Document))

;Создаем временный объект "точка"
(setq point-temp (vla-AddPoint S_ModelSpace (vlax-3D-point '(0.0 0.0 0.0))))

;Добавляем временный объект в список объектов реактора
(vlr-owner-add stat-vlr-object point-temp)

;Удаляем из списка объектов реактора наш блок "Линия"
(vlr-owner-remove stat-vlr-object stat-object)

;Создаем список всех свойств блока "Линия"
  (setq
    lst_temp
     (vlax-safearray->list
       (vlax-variant-value (vla-GetDynamicBlockProperties stat-object))
     )
  )

;Получаем указатель на свойство "Distance"
  (foreach item	lst_temp
    (if	(= (vla-get-PropertyName item) "Distance")
      (setq naimenov item)
    )
  )

;Устанавливаем нужную длинну линии
(vla-put-Value naimenov 500.00)

;Добавляем блок "Линия" в список объектов реактора
(vlr-owner-add stat-vlr-object stat-object)

;Удаляем из списка объектов реактора временный объект "точка"
(vlr-owner-remove stat-vlr-object point-temp)

;Убиваем временный объект "точка"
(vla-Delete point-temp)
)

;============ Функция действия реактора к блоку "Линия" ============================

(defun VLR-SDD22 (a-object b-vlr-object c-data / )

;Сохраняем указатель на объект - блок "линия
 (setq stat-object a-object)

;Сохраняем указатель на объект - реактор
 (setq stat-vlr-object b-vlr-object)

;Ставим в очередь выполнение функции modline
  (vla-SendCommand 
    (vla-get-ActiveDocument (vlax-get-acad-object)) 
    "(modline) ")

;Сваливаем из реактора
)
Вложения
Тип файла: dwg
DWG 2004
Линия.dwg (24.5 Кб, 1364 просмотров)
Тип файла: lsp Линия.lsp (1.8 Кб, 136 просмотров)
Supermax вне форума  
 
Автор темы   Непрочитано 28.11.2008, 22:31
#15
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Вся фишка заключается в том, что нельзя из реактора удалять все указатели на объекты, иначе он умрет. Вот поэтому и надо создавать временный элемент, чтобы он дал возможность выбросить из реактора элемент, требующий редакции.
Supermax вне форума  
 
Непрочитано 28.11.2008, 22:51
#16
Baldares


 
Регистрация: 17.10.2008
Саратов
Сообщений: 426


Supermax, ни фига не понятно.
А в какой момент, и где прописано, прицепка реактора к блоку?
Скопировал блок в другой файл, загрузил лисп, и не работает реактор.
А в оригинале, первый раз еще можно двигануть стрелку у блока, но при этом длина устанавливается принудительно в 500, а далее вообще не сместа.
Так где же цепляла реактора к блоку сидит?
Или тут глупые вопросы ни-ни.
Baldares вне форума  
 
Непрочитано 29.11.2008, 00:05
#17
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Supermax, даже если забыть про #16, ты постоянно создаешь "левый" объект. Ты, похоже, еще не "ловил" ошибку переполнения количества объектов...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 29.11.2008, 09:46
#18
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Отвечаю сразу обоим.
Есть файл, в нем есть блок, на блок навешен реактор, реактор не в блоке, а в рисунке, поскольку он может следить за несколькими объектами. Копирование блока из файла в файл к копированию реактора не приводит! Его надо заново устанавливать.

Установка реактора пост #6
Код:
[Выделить все]
; Указываем на нужный нам объект:
(setq obj (vlax-ename->vla-object (car (entsel))))
;Устанавливаем на него реактор модификации 
(setq reactor1 (vlr-object-reactor (list obj) nil (list '(:VLR-modified . vlr-sdd22))))
;Делаем его постоянным
(vlr-pers reactor1)
Если открыть блок редактором блоков и добавить туда, или перенести, или все, что угодно, лишь бы осталось то наименование динамического свойства, которое в реакторе записано. Можно даже все стереть и заново нарисовать, но НАИМЕНОВАНИЕ свойства должно быть прежним (чтобы реактор мог его найти и установить заданное значение), то реактор от этого, с блока не исчезнет.

Временный объект, на то и временный, что он создается->устанавливается->...->снимается->удаляется. Это не блок и переполнения библиотеки не будет. Мой реактор всегда содержит только один элемент, и только при срабатывании в нем появляется второй ВРЕМЕННО! Если надо сделать реактор, следящий сразу за группой объектов, то там не надо делать временных объектов.
Kpblc, в лиспе каждая строчка подписана!
Supermax вне форума  
 
Автор темы   Непрочитано 29.11.2008, 14:48
#19
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Есть один подводный камень. Не знаю как на других Автокадах, а у меня на 2007 он присутствует.

Если взять мой блок с прикрученным реактором и не растягивать его ручками, а залезть в пропертиес и там установить значение длинны линии цифрами, то блок начинает себя вести очень хитро. Ручка всегда возвращается на установленную длинну, а вот линия все удлинняется, и удлинняется (если ручку в сторону удлиннения перемещать), или укорачивается (если ручку перемещать внутрь). Явный баг Автокада, но если он у всех, его можно использовать.
Supermax вне форума  
 
Непрочитано 29.11.2008, 15:16
#20
Baldares


 
Регистрация: 17.10.2008
Саратов
Сообщений: 426


Да такаяже фишка. Акад 2008 MEP рус., акад 2009 рус.
И как енто будешь использовать?
Baldares вне форума  
 
Автор темы   Непрочитано 29.11.2008, 15:51
#21
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Пока копаю вглубь. Ниточку уже схватил, распутываю.
Нарушение идет только в конкретном вхождении блока, реактор на вхождение вешается, а на остальные вхождения не распостраняется баг.
Только при изменении динамических свойств из панели пропертиес, другие свойства блока (не динамические) типа поворот, слой и пр. к багу не приводят.
Баг возникает, даже если другие динамические свойства пошевелить.
Заметил, что изменение динамических свойств с панели не реагирует реактор. Если из ком. строки запускать
Код:
[Выделить все]
(vla-put-Value naimenov 1000.00)
то все путем.

Копаю, короче, ждите.
Supermax вне форума  
 
Автор темы   Непрочитано 29.11.2008, 19:55
#22
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Обнаружил причину. Объекты влегкую добавляются в список реактора, но не удаляются из него, если изменение блока идет через панель пропертиес. А если за ручки двигать - все удаляется.
Попробуем удалить иначе.
Supermax вне форума  
 
Автор темы   Непрочитано 29.11.2008, 20:33
#23
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Очень, скажу странно не удаляются. В списке владельцев реактора объект исчезает, а реактор по прежнему продолжает реагировать на этот объект. И вот что еще интересно. Если добавлять в процессе выполнения функции modline объект, то реактор реагировать начинает и на него, а вот если его тоже в процессе удалять, то и реагировать на него перестает. Правда это точка, а не динамический блок. У меня сейчас нонсенс на экране. Реактор, у которого списов владельцев - nil показывает, а все равно продолжает реагировать на изменения свойств динамического блока.
Supermax вне форума  
 
Автор темы   Непрочитано 29.11.2008, 20:38
#24
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Срочно нужна альтернатива немодальному окну "Свойства". Это окно не корректно работает с реакторами! Я у Полещука вроде видел. Пойду клянчить.
Supermax вне форума  
 
Непрочитано 29.11.2008, 22:08
#25
Sleekka

-
 
Регистрация: 24.07.2005
Москва
Сообщений: 1,335


По поводу изменения объекта объектным реактором (пусть даже после завершения) я бы побоялся использовать.
А вот сама методика реактор + Vlasendcommand - это плюсадин, у меня так dblclk реактор работеат. Такчто ИМХО любые реакторы кроме объектных - вроде безопасно.
По поводу программирования в вертикальных решениях и уж тем более c СПДС сочувствую - их надо первыми снести, никаких Object Extensions. Лисп и родные объекты акада вот залог успеха.
Sleekka вне форума  
 
Непрочитано 29.11.2008, 22:15
#26
Sleekka

-
 
Регистрация: 24.07.2005
Москва
Сообщений: 1,335


И еще Supermax у меня задача с динблоками похожая счас стоит только я ее запихал в долгий ящик, а по ночам думаеца ее решать не через объектный реактор а через sysvar реактор, потипу как сделано в макросах типа как на кнопке copy:
Код:
[Выделить все]
$M=$(if,$(eq,$(substr,$(getvar,cmdnames),1,4),GRIP),_copy,^C^C_copy)
Но я сам пока не пытался - так на уровне идеи высказываю.
Sleekka вне форума  
 
Непрочитано 29.11.2008, 22:47
#27
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Supermax, Реактор в функции modline можно временно деактивировать, а потом активировать снова.
Код:
[Выделить все]
;============= Функция редактирования динамического блока "Линия" =================
(defun modline ( )
;;;Не удаляем, а деактивируем реактор
(VLR-remove stat-vlr-object);;;VVA
 ;Создаем список всех свойств блока "Линия"
  (setq
    lst_temp
     (vlax-safearray->list
       (vlax-variant-value (vla-GetDynamicBlockProperties stat-object))
     )
  )
;Получаем указатель на свойство "Distance"
  (foreach item	lst_temp
    (if	(= (vla-get-PropertyName item) "Distance")
      (setq naimenov item)
    )
  )
;Устанавливаем нужную длинну линии
(vla-put-Value naimenov 500.00)
;;;Активируем реактор  
(VLR-add stat-vlr-object) ;;;VVA
)
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 29.11.2008, 22:48
#28
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Что такое панель Properties? Правильно - это немодальное окно ActiveХ элемента. Я давно заметил, что когда оно открыто, то очень трудно вращать сложные объекты, а когда закрыто - легко. Понятное дело, туда идет постоянная подгрузка текущих значений выделенных элементов и если их много и они стремительно меняют свои значения,скажем при перемещении, то процесс заметно тормозится.

Где-то в глубине автокада есть словари с реакторами. Я встречал как-то, но где - не помню. Скорее всего, этот ActiveX элемент не все словари регенерирует. Глюк именно на динамических свойствах. Я другой пример сделал. Полилинию в координаты 0,0,0 перемещаю насильно, если ее от туда сдвинули - все как часы, в том числе и при изменении координаты из меню пропертиес.

Только динамические свойства глючат. Либо надо найти механизм их коррекции, либо отказаться от услуг этой панели.

Реакторы тут не причем! Все корректно работает, это только динамизм мешает удалять из реактора указатель на объект.

О! Еще один опыт в голову пришел.
Supermax вне форума  
 
Автор темы   Непрочитано 29.11.2008, 22:58
#29
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


VVA, если у меня только линия не становится на место, а ручка становится, то у тебя уже и ручка не становится. Это я имею в виду глюк с изменением длинны через меню пропертиес. А так -

Ща мужики, мы эту заразу выловим!
Supermax вне форума  
 
Автор темы   Непрочитано 29.11.2008, 23:03
#30
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


VVA, у тебя ситуация такая - ты деактивируешь, он при проверке функцией vlr-added-p пишет, что отключен, а реактор все равно продолжает реагировать на изменение объекта (по всем параметрам, даже по изменению угла поворота блока).

Последний раз редактировалось Supermax, 29.11.2008 в 23:12.
Supermax вне форума  
 
Автор темы   Непрочитано 29.11.2008, 23:10
#31
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Кто знает как программно закрыть окно пропертиес?
Supermax вне форума  
 
Непрочитано 29.11.2008, 23:29
#32
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Один из вариантов: командой _propertiesclose
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 29.11.2008, 23:53
#33
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Даю не динамический блок "квадрат" и две функции к этому файлу.
Поглядите какая картина с работой из под окна свойств. И все восстанавливается, как только начинаешь работать с ручками.
Код:
[Выделить все]
(vl-load-com)
;============= Функция редактирования динамического блока "квадрат" =================
(defun modkbadrat (/ S_Document S_ModelSpace point-temp)
(command "_propertiesclose")
(alert "Этот блок нельзя перемещать!\nШутка")
;Получаем указатели на активный документ и пространство модели
  (setq S_Document (vla-get-ActiveDocument (vlax-get-acad-object)))
  (setq S_ModelSpace (vla-get-ModelSpace S_Document))

;Создаем временный объект "точка"
(setq point-temp (vla-AddPoint S_ModelSpace (vlax-3D-point '(0.0 0.0 0.0))))

;Добавляем временный объект в список объектов реактора
(vlr-owner-add stat-vlr-object point-temp)

;Удаляем из списка объектов реактора наш блок "квадрат"
(vlr-owner-remove stat-vlr-object stat-object)

;Устанавливаем блок "квадрат" точкой вставки в 0,0,0
(vla-put-InsertionPoint stat-object (vlax-3D-point '(0.0 0.0 0.0)))

;Добавляем блок "Линия" в список объектов реактора
(vlr-owner-add stat-vlr-object stat-object)

;Удаляем из списка объектов реактора временный объект "точка"
(vlr-owner-remove stat-vlr-object point-temp)

;Убиваем временный объект "точка"
(vla-Delete point-temp)
)

;============ Функция действия реактора к блоку "квадрат" ============================

(defun VLR-SDD22 (a-object b-vlr-object c-data / )

;Сохраняем указатель на объект - блок "квадрат"
 (setq stat-object a-object)

;Сохраняем указатель на объект - реактор
 (setq stat-vlr-object b-vlr-object)

;Ставим в очередь выполнение функции modkbadrat
  (vla-SendCommand 
    (vla-get-ActiveDocument (vlax-get-acad-object)) 
    "(modkbadrat) ")

;Сваливаем из реактора
)
Вложения
Тип файла: dwg
DWG 2004
Квадрат.dwg (21.8 Кб, 1028 просмотров)
Тип файла: lsp Квадрат.lsp (1.6 Кб, 92 просмотров)
Supermax вне форума  
 
Автор темы   Непрочитано 29.11.2008, 23:55
#34
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


VVA, выключение окна, как ты увидишь, не решает проблему. Успевает зараза наломать дров в реакторе.
Попробуй еще свою функцию с отключением реактора на время.
Supermax вне форума  
 
Непрочитано 30.11.2008, 00:06
#35
Baldares


 
Регистрация: 17.10.2008
Саратов
Сообщений: 426


Supermax, тебе пора свой Supercad писать где не будет ГАДостей.
Не помогает _propertiesclose
Baldares вне форума  
 
Автор темы   Непрочитано 30.11.2008, 14:28
#36
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


ВСЕ!

Проблема решена!

Код:
[Выделить все]
(vl-load-com)
;====Функция запуска скрипт-файла сценария, создается новый дочерний процесс.===========
(defun dwgru-wscript-exec ( WScriptFile WCchoice / svr svr1)
  (setq svr (vlax-get-or-create-object "WScript.Shell"))
  (if (or  (= WCchoice nil) (= WCchoice ""))
      (setq svr1 (vlax-invoke-method svr "Exec" (strcat "WScript " WScriptFile)))
      (if (= (strcase WCchoice) "C") 
        (setq svr1 (vlax-invoke-method svr "Exec" (strcat "CScript " WScriptFile)))
        (progn (vlax-invoke-method svr "Popup" 
           "Не правильно указан аргумент WCchoice! \n nil или \"\" - запуск скрипт-файла через WScript.ехе 
           \"C\" - запуск скрипт-файла через СScript.ехе" "30" 
           "Ошибка в аргументе функции dwgru-wscript-exec" "48")
         (quit))
      ); конец if-2
    ); конец if-1
   (vl-catch-all-apply '(lambda () (vlax-release-object svr)))
   (print svr1)
  ); конец defun 


;============= Функция редактирования динамического блока "Линия" =================
(defun modline (/ S_Document S_ModelSpace point-temp)
;освобождаем объект Script
(vl-catch-all-apply '(lambda () (vlax-release-object script)))

;Деактивируем реактор
(VLR-remove stat-vlr-object);;;VVA

;Создаем список всех свойств блока "Линия"
  (setq
    lst_temp
     (vlax-safearray->list
       (vlax-variant-value (vla-GetDynamicBlockProperties stat-object))
     )
  )

;Получаем указатель на свойство "Distance"
  (foreach item	lst_temp
    (if	(= (vla-get-PropertyName item) "Distance")
      (setq naimenov item)
    )
  )

;Устанавливаем нужную длинну линии
(vla-put-Value naimenov 500.00)

;Активируем реактор  
(VLR-add stat-vlr-object) ;;;VVA
)

;============ Функция действия реактора к блоку "Линия" ============================

(defun VLR-SDD22 (a-object b-vlr-object c-data / ) 
;Сохраняем указатель на объект - блок "линия
 (setq stat-object a-object)
;Сохраняем указатель на объект - реактор
 (setq stat-vlr-object b-vlr-object)
;записываем имя временного файла
(setq Fdcl "Sel555.vbs")
;Создаем путь к временному файлу
(setq Fdcl (strcat (VL-FILENAME-DIRECTORY(vl-filename-mktemp Fdcl)) "\\" Fdcl))   
(vl-file-delete Fdcl)  ;Если есть такой файл, то его убить, поскольку он каждый раз создается с 0.

(setq dsl0055 (open Fdcl "w")) ;Открываем и заполняем файл Sel555.vbs 
(write-line "Set AutoCAD = GetObject(, \"AutoCAD.Application\")" dsl0055)
(write-line "Set ActiveDocument = AutoCAD.ActiveDocument" dsl0055)
(write-line "WScript.Sleep 10" dsl0055)
(write-line "ActiveDocument.SendCommand \"(modline) \"" dsl0055)
(close dsl0055)
;Запускаем скрипт.
(setq script (DwgRu-WScript-Exec Fdcl ""))

;Сваливаем из реактора
)
Создаем временный файл сценария на VBScript-e и запускаем через него.
На Сером форуме подсказали про другой процесс.

Отредактировал, как VVA подсказал - тоже работает!!!

Последний раз редактировалось Supermax, 30.11.2008 в 14:49.
Supermax вне форума  
 
Автор темы   Непрочитано 30.11.2008, 20:16
#37
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Опишу механизм нарушения работы реактора.
ActiveX элемент "Свойства" (не знаю как он реально называется) предназначен для а) - демонстрации свойств объектов и б) - для изменения этих свойств, если они то позволяют.
Цепочка действий идет такая
- Собираются данные об объекте (или группе объектов);
- Передаются в окно ActiveX компонента
- Если пользователь изменил значение в окне - это значение анализируется на предмет совместимости и если да - передается в объект
- Опять собираются данные с объекта (или группы объектов)

Где-то в этой цепочке ActiveX компоненту нужна командная строка и что получается:
- Передаются в окно ActiveX компонента
- Если пользователь изменил значение в окне - это значение анализируется на предмет совместимости и если да - передается в объект
- срабатывает реактор и посылает в командную строку (в очередь) данные
- Начинается работа по изменению свойства блока
- А работа ActiveX компонент "Свойства" пытается в это время получить данные с объекта.

Где-то в общих чертах так. Ну, так нам спешить некуда, подождем и после отправим нашу функцию в командную строку.
Supermax вне форума  
 
Непрочитано 03.08.2010, 09:17
#38
Ax3

Programming, automation, CADs, GISs. "Теплоком"
 
Регистрация: 02.02.2007
Россия, Санкт-Петербург
Сообщений: 306


Спасибо, Supermax, тебе за эту тему. Очень помог мне решить вот эту проблему: http://forum.dwg.ru/showthread.php?p=604338#post604338
__________________
На LISPе можно мыслить!

Последний раз редактировалось Ax3, 03.08.2010 в 09:30.
Ax3 вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > AutoLISP: Работа с реакторами



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
передача данных из AutoLisp в Excel Victorovich LISP 2 03.12.2011 22:28
Параметрическая библиотека в autoLISP joisegatoi LISP 8 18.06.2007 18:39
Autolisp и Visual Basic Книга Piton LISP 6 27.02.2006 09:54