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

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

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

Ответ
Поиск в этой теме
Непрочитано 28.11.2008, 12:43
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)
Тут можно и сообщение добавить, о том, что функции введены и если такой файл есть, то добавить этот текст в него.
Просмотров: 12711
 
Автор темы   Непрочитано 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