Visretain и слои внешних ссылок
Системная переменная VISRETAIN существует достаточно давно и ее описание вроде бы внятно и понятно. Но вот стоит поставить ее равной 1 и вылезают некоторые моменты, предусмотреть которые я в свое время не смог.
Файлы dwg я не предоставляю - ситуацию можно смоделировать и так. Все выполняется внутри одной сессии AutoCAD. Версия AutoCAD не важна (ситуацию удалось смоделировать на AutoCAD 2009, 2013, 2016).
Создаем новый файл XRef.dwg, в котором создаются два-три новых слоя с любыми настройками (например, Layer1, Layer2, Layer3). На каждый слой помещаем хотя бы один примитив. Сохраняем файл и вставляем его как внешнюю ссылку в файл Common.dwg. Тип внешней ссылки роли не играет. В файле Common.dwg для visretain установлено значение 1. Вызовем диспетчер слоев файла Common.dwg:
Откроем ссылку XRef.dwg из-под Common.dwg. В XRef.dwf выполним удаление слоя Layer3:
Сохраняем и закрываем Xref.dwg.
Естественно, при активации окна Common.dwg AutoCAD сообщает об изменении файла внешней ссылки. Обновляем ее и смотрим на диспетчер слоев:
Интересно, но факт: слой Xref|Layer3 не удален в текущем файле! Если честно, я ожидал, что удаление слоя должно автоматически обновлять состояние внешней ссылки независимо ни от чего. Так же, как срабатывает добавление или изменение имени слоя. Программное решение без перезагрузки Common.dwg получилось таким:
- (if *vlr-xref*
- (progn
- (setq *vlr-xref* nil)
- (vlr-remove-all :vlr-xref-reactor)
- ) ;_ end of progn
- ) ;_ end of if
- (if (not *vlr-xref*)
- (setq *vlr-xref*
- (vlr-xref-reactor "kpblc-xref-reactor"
- '((:vlr-xrefsubcommandreloaditem . _kpblc-vlr-xref-reloaditem)
- )
- ) ;_ end of vlr-command-reactor
- ) ;_ end of setq
- ) ;_ end of if
- (defun _kpblc-vlr-xref-reloaditem (react datas / obj name)
- (if (and (= (getvar "visretain") 1)
- (= (car datas) 3)
- (setq obj (car (vl-remove-if-not
- (function
- (lambda (x)
- (= (vla-get-objectid x) (cadr datas))
- ) ;_ end of lambda
- ) ;_ end of function
- ((lambda (/ res)
- (vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
- (setq res (cons blk res))
- ) ;_ end of vlax-for
- res
- ) ;_ end of lambda
- )
- ) ;_ end of vl-remove-if-not
- ) ;_ end of car
- ) ;_ end of setq
- ) ;_ end of and
- (progn
- ; Начинаем обработку
- (setq name (vla-get-name obj))
- (vlax-for item (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
- (vl-catch-all-apply
- (function
- (lambda ()
- (vla-delete item)
- ) ;_ end of lambda
- ) ;_ end of function
- ) ;_ end of vl-catch-all-apply
- ) ;_ end of vlax-for
- ) ;_ end of progn
- ) ;_ end of if
- ) ;_ end of defun
Следует отметить один момент: обновляется только информация об удаленных слоях. Не выполняется обновление описания слоя: для решения этой задачи придется использовать ObjectDBX-доступ к неактивному документу, что неимоверно удлинит код.
Получается, что VISRETAIN сохраняет не только переопределенные цвета, типы и веса линий, а также описания слоев, но и перечень слоев - даже если их не переопределяли. А есть они на самом деле или нет - это уже дело шестнадцатое. При этом достаточно установить visretain в 0 - и все, абсолютно все! изменения в слоях файла внешней ссылки моментально отображаются в Common.dwg.
Автор: Алексей Кулик
Обсуждение: http://adn-cis.org/forum/index.php?topic=2894
Опубликовано 03.08.2015