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

03/08/2015

Visretain и слои внешних ссылок

Системная переменная VISRETAIN существует достаточно давно и ее описание вроде бы внятно и понятно. Но вот стоит поставить ее равной 1 и вылезают некоторые моменты, предусмотреть которые я в свое время не смог.

Файлы dwg я не предоставляю - ситуацию можно смоделировать и так. Все выполняется внутри одной сессии AutoCAD. Версия AutoCAD не важна (ситуацию удалось смоделировать на AutoCAD 2009, 2013, 2016).

Создаем новый файл XRef.dwg, в котором создаются два-три новых слоя с любыми настройками (например, Layer1, Layer2, Layer3). На каждый слой помещаем хотя бы один примитив. Сохраняем файл и вставляем его как внешнюю ссылку в файл Common.dwg. Тип внешней ссылки роли не играет. В файле Common.dwg для visretain установлено значение 1. Вызовем диспетчер слоев файла Common.dwg:

common01

Откроем ссылку XRef.dwg из-под Common.dwg. В XRef.dwf выполним удаление слоя Layer3:

common02

Сохраняем и закрываем Xref.dwg.

Естественно, при активации окна Common.dwg AutoCAD сообщает об изменении файла внешней ссылки. Обновляем ее и смотрим на диспетчер слоев:

common03

Интересно, но факт: слой Xref|Layer3 не удален в текущем файле! Если честно, я ожидал, что удаление слоя должно автоматически обновлять состояние внешней ссылки независимо ни от чего. Так же, как срабатывает добавление или изменение имени слоя. Программное решение без перезагрузки Common.dwg получилось таким:

Код - Auto/Visual LISP: [Выделить]
  1. (if *vlr-xref*
  2.   (progn
  3.     (setq *vlr-xref* nil)
  4.     (vlr-remove-all :vlr-xref-reactor)
  5.     ) ;_ end of progn
  6.   ) ;_ end of if
  7.  
  8. (if (not *vlr-xref*)
  9.   (setq *vlr-xref*
  10.          (vlr-xref-reactor "kpblc-xref-reactor"
  11.                            '((:vlr-xrefsubcommandreloaditem . _kpblc-vlr-xref-reloaditem)
  12.                              )
  13.                            ) ;_ end of vlr-command-reactor
  14.         ) ;_ end of setq
  15.   ) ;_ end of if
  16.        
  17. (defun _kpblc-vlr-xref-reloaditem (react datas / obj name)
  18.   (if (and (= (getvar "visretain") 1)
  19.            (= (car datas) 3)
  20.            (setq obj (car (vl-remove-if-not
  21.                             (function
  22.                               (lambda (x)
  23.                                 (= (vla-get-objectid x) (cadr datas))
  24.                                 ) ;_ end of lambda
  25.                               ) ;_ end of function
  26.                             ((lambda (/ res)
  27.                                (vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
  28.                                  (setq res (cons blk res))
  29.                                  ) ;_ end of vlax-for
  30.                                res
  31.                                ) ;_ end of lambda
  32.                              )
  33.                             ) ;_ end of vl-remove-if-not
  34.                           ) ;_ end of car
  35.                  ) ;_ end of setq
  36.            ) ;_ end of and
  37.     (progn
  38.           ; Начинаем обработку
  39.       (setq name (vla-get-name obj))
  40.       (vlax-for item (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
  41.         (vl-catch-all-apply
  42.           (function
  43.             (lambda ()
  44.               (vla-delete item)
  45.               ) ;_ end of lambda
  46.             ) ;_ end of function
  47.           ) ;_ end of vl-catch-all-apply
  48.         ) ;_ end of vlax-for
  49.       ) ;_ end of progn
  50.     ) ;_ end of if
  51.   ) ;_ end of defun

Следует отметить один момент: обновляется только информация об удаленных слоях. Не выполняется обновление описания слоя: для решения этой задачи придется использовать ObjectDBX-доступ к неактивному документу, что неимоверно удлинит код.

Получается, что VISRETAIN сохраняет не только переопределенные цвета, типы и веса линий, а также описания слоев, но и перечень слоев - даже если их не переопределяли. А есть они на самом деле или нет - это уже дело шестнадцатое. При этом достаточно установить visretain в 0 - и все, абсолютно все! изменения в слоях файла внешней ссылки моментально отображаются в Common.dwg.

Автор: Алексей Кулик

Обсуждение: http://adn-cis.org/forum/index.php?topic=2894

Опубликовано 03.08.2015