Неожиданно обнаружилась опасная ошибка:
При работе в "максимизированном" viewport в AutoCAD 2005 наши функции рисования при работе в этом режиме создают объекты в PaperSpace с координатами, заданными в координатах модели. Причем только часть объектов, создаваемых без использования функции command.
Расследование "по горячим следам" показало, что то же самое происходит при рисовании в пространстве модели через окно viewport.
Во всех функциях рисования объектными методами указывается рабочее пространство, в которое должен добавляться создаваемый объект. Текущее рабочее пространство определяется функцией ru-obj-active-space.
Активное пространство
(defun ru-obj-active-space ()
(if (= 1
(vlax-get-activespace (ru-obj-get-active-document)))
(ru-obj-get-model-space)
(ru-obj-get-paper-space)
)
) ;_ end of defun
(if (= 1
(vlax-get-activespace (ru-obj-get-active-document)))
(ru-obj-get-model-space)
(ru-obj-get-paper-space)
)
) ;_ end of defun
Внутри используется стандартная функция vlax-get-activespace, которая должна возвращать 1 при нахождении в пространстве модели и 0 - при нахождении в пространстве листа.
Однако выяснилось, что в случае проникновения в пространство модели через "дыру" viewport, созданного в пространстве листа, функция vlax-get-activespace всегда возвращает 0. Из-за этого и происходят все последующие ошибки.
На первый взгляд, это явная ошибка AutoCAD. Фактически это просто не очень удачное название, наталкивающее на мысль, что функция действительно возвращает код активного пространства. На что и "купились" мы.
Тщательное изучение справки показало, что надо использовать не только значение, возвращаемое функцией vlax-get-activespace, т.е. свойства ActiveSpace, но и уточнять свойство MSpace активного документа. Именно оно позволяет определить, в каком пространстве производится редактирование. Выяснять значение MSpace нужно при нахождении на вкладке листа.
Возможные значения MSpace:
TRUE: разрешается редактирование модели.
FALSE: не разрешается редактирование модели.
Поиски в Интернете показали, что все (обнаруженные) авторы определяют рабочее пространство так же, как и мы. То есть неправильно.
Единственным исключением явился наш коллега Петр Лоскутов, приводивший на форумах примеры функций рисования с правильным определением пространства.
Определял он его между прочими делами, не вынося в отдельную функцию и не заостряя внимание на этом вопросе.
Приводим правильный код:
Определение активного пространства
(defun ru-obj-active-space (/ active_doc)
(setq active_doc (ru-obj-get-active-document))
(if (and (zerop (vla-get-activespace active_doc))
(= :vlax-false (vla-get-mspace active_doc))
) ;_ end of and
(vla-get-paperspace active_doc)
(vla-get-modelspace active_doc)
) ;_ end of if
) ;_ end of defun
(setq active_doc (ru-obj-get-active-document))
(if (and (zerop (vla-get-activespace active_doc))
(= :vlax-false (vla-get-mspace active_doc))
) ;_ end of and
(vla-get-paperspace active_doc)
(vla-get-modelspace active_doc)
) ;_ end of if
) ;_ end of defun
Код функции прозрачен и не требует комментариев.
Заметим также, что мы в очередной раз убедились в правильности выноса повторяющегося кода в отдельные функции. Исправление только одной из них позволило восстановить работоспособность всех программ и функций сразу.
Если бы мы включали простой (но оказавшийся ошибочным) участок кода определения пространства в каждую функцию рисования, нам пришлось бы внести исправления в сотни файлов.
Кроме того, можно сделать вывод, что большинство разработчиков (как и мы) не тестировали свои программы при рисовании в модели через дыру в листе. Или использовали функцию command.