Очистка файлов от ненужных данных LineStyle DGN в AutoCAD.

Автор Тема: Очистка файлов от ненужных данных LineStyle DGN в AutoCAD.  (Прочитано 108677 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Так вот, практически "с ножом к горлу" для масштабов аннотаций нужно выполнить  (if (> (check-dict2 nil "ACAD_SCALELIST") 100) (command "_-scalelistedit" "_d" "*" "_e"))
Не читаешь ты то что я пишу, а жаль. Повторюсь. Средствами lisp на этапе сохранения чертежа можно лишь известить о критическом количестве масштабов аннотаций, но нельзя прервать сохранение и выполнить команду очистки.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Не читаешь ты то что я пишу, а жаль.
Александр, я читал это. Просто, как я уже написал, я натолкнулся на статью Алексея про реакторы с фразой "Если "с ножом к горлу" надо использовать командную строку (бывает такое), то следует использовать механизм vla-sendcommand для текущего документа", вот и появилась надежда  ::)
Если Алексей скажет, что такое невозможно, значит не судьба и обойдёмся алертом...

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
Не уверен, что сегодня успею хоть что-то сделать...
Очистка масштабов аннотаций может быть выполнена и без команд:
Код - Auto/Visual Lisp [Выбрать]
  1. (if (getvar "cannoscale")
  2.     (foreach scale (mapcar (function cdr)
  3.                            (vl-remove-if-not
  4.                              (function (lambda (x) (= (car x) 350)))
  5.                              (dictsearch (namedobjdict) "acad_scalelist")
  6.                              ) ;_ end of vl-remove-if-not
  7.                            ) ;_ end of mapcar
  8.         (vl-catch-all-apply
  9.           (function
  10.             (lambda ()
  11.               (vla-delete (vlax-ename->vla-object scale))
  12.               ) ;_ end of lambda
  13.             ) ;_ end of function
  14.           ) ;_ end of vl-catch-all-apply
  15.       ) ;_ end of foreach
  16.     )
Код выдран "с мясом" из другого проекта. А очистка, в частности, у меня на сайте рассматривалась: http://autolisp.ru/2014/03/24/clear-dwg-at-opening/
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр, я читал это. Просто, как я уже написал, я натолкнулся на статью Алексея про реакторы с фразой "Если "с ножом к горлу" надо использовать командную строку (бывает такое), то следует использовать механизм vla-sendcommand для текущего документа", вот и появилась надежда  ::)
Если Алексей скажет, что такое невозможно, значит не судьба и обойдёмся алертом...
Код будет запущенный SendCommand будет выполнен уже после сохранения файла. Соотвественно его придётся сохранить повторно. Если обработчик BeginSave сработал при закрытии документа, то SendCommand отправит команду неизвестно куда, и документ будет уже закрыт, так что сохранить его в очищенном виде будет невозможно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Не уверен, что сегодня успею хоть что-то сделать...
Очистка масштабов аннотаций может быть выполнена и без команд:
Алексей, как будет время, естественно :)
Главное, чтобы этот лисп был аналогичен команде (command "_-scalelistedit" "_d" "*" "_e"), то есть очистке именно неиспользуемых масштабов, а не полному сбросу масштабов, как это делает автокад по-умолчанию при большом количестве масштабов аннотаций.
Код выдран "с мясом" из другого проекта. А очистка, в частности, у меня на сайте рассматривалась: http://autolisp.ru/2014/03/24/clear-dwg-at-opening/
Кстати, как я и писал в этой ветке, принудительная очистка словаря AcDgnLS чревата определёнными последствиями для тех, кто умудряется использовать типы линий DGN (понимаю, что таких случаев может быть мало, но, тем не менее, я напоролся).
Код будет запущенный SendCommand будет выполнен уже после сохранения файла
Алексей же вроде написал, что можно чистить масштабы лиспом... ::)
« Последнее редактирование: 12-05-2016, 12:04:55 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
Александр предупредил о возникающих проблемах (возможно, даже фатальных ;)).
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Очистка масштабов аннотаций может быть выполнена и без команд:
Алексей, этот лисп удаляет ВСЕ масштабы аннотаций, даже используемые. Так не надо. Надо именно неиспользуемые, или тогда никак, только алерт.
Кстати, если после выполнения этого лиспа зайти в список масштабов, то акад валится с Fatal Error. Проверил 3 раза.
« Последнее редактирование: 12-05-2016, 15:24:20 от Подшиваленко Дмитрий »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Алексей, этот лисп удаляет ВСЕ масштабы аннотаций, даже используемые. Так не надо. Надо именно неиспользуемые,...
Снова упираемся в ограничения lisp. В нём нет средств проверки "используется/не используется". Нужно сканировать всё базу чертежа.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Поскольку Алексей, как я понял, немного подзабросил эту тему, пришлось ковыряться самому.
Получился следующий код для реактора с очисткой масштабов:
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2. (load "check-dict2.lsp") ;функция отсюда: http://adn-cis.org/forum/index.php?topic=709.msg20101#msg20101
  3.  
  4. (if *adn-vlr-cmd*
  5.   (progn (vl-remove *adn-vlr-cmd*) (setq *adn-vlr-cmd* nil))
  6. ) ;_ end of if
  7.  
  8. (if (not *adn-vlr-cmd*)
  9.   (setq *adn-vlr-cmd* (vlr-command-reactor "adn-cmd-reactor" '((:vlr-commandwillstart . _adn-vlr-cmd-start))))
  10. ) ;_ end of if
  11.  
  12. (defun _adn-vlr-cmd-start (react cmd / datas)
  13.  (setq cmd (strcase (car cmd)))
  14.  (cond
  15.   ((member cmd '("QSAVE" "SAVE" "SAVEAS"))
  16.    (setq sc (check-dict2 nil "ACAD_SCALELIST"))
  17.    (if (> sc 100)
  18.     (progn
  19.      (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_-scalelistedit _d" "\r" "*" "\r" "_e" "\r")) ;Очистка неиспользуемых масштабов аннотаций
  20.      (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) "_QSAVE ") ;сохраняем, ибо очистка происходит после выполнения команды сохранения
  21.      (alert (strcat "ВНИМАНИЕ! Этот чертёж содержал "(itoa sc)" масштабов аннотаций. НЕИСПОЛЬЗУЕМЫЕ масштабы были удалены!"))
  22.     ) ;progn
  23.    ) ;if sc
  24.    (setq dg (check-dict2 nil "ACAD_DGNLINESTYLECOMP"))
  25.    (if (> dg 10000) (alert (strcat "ВНИМАНИЕ! Этот чертёж содержит "(itoa dg)" объектов DGN. Необходима очистка!")))
  26.   )
  27.  ) ;_ end of cond
  28. ) ;_ end of defun
Код потестил, вроде рабочий.
Алексей, если я где-то накосячил в коде, поправь, пожалуйста.
И маленькая просьба напоследок.
Можешь написать отдельно функцию определения количества записей символьной таблицы, наподобие функции check-dict2 ? (в последнем коде у тебя подсчёт присутствует вроде).

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
Я не забил и не забыл, просто работы была тьма.
В твоем коде ты получишь бесконечный цикл, скорее всего: реактор срабатывает на начало вызова (помимо всего прочего) _qsave, внутри него ты снова вызываешь _qsave и т.д. Далее - ты вводишь соответствующие ограничения прямо в код. С моей точки зрения, это не самое лучшее решение. Идеальным был бы вариант выноса этого богатства во внешний настроечный файл, откуда все и считывается. Но дело твое ;)
P.S. ИМХО код должен быть наподобие:
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun check-dict2 (doc name / dict)
  4.   ;; doc - Документ (nil - текущий)
  5.   ;; name - имя словаря
  6.   (if (and name
  7.            (= (type (setq dict (vl-catch-all-apply
  8.                                  (function (lambda ()
  9.                                              (vla-item (vla-get-dictionaries
  10.                                                          (cond (doc)
  11.                                                                (t (vla-get-activedocument (vlax-get-acad-object)))
  12.                                                                ) ;_ end of cond
  13.                                                          ) ;_ end of vla-get-dictionaries
  14.                                                        name
  15.                                                        ) ;_ end of vla-item
  16.                                              ) ;_ end of lambda
  17.                                            ) ;_ end of function
  18.                                  ) ;_ end of vl-catch-all-apply
  19.                           ) ;_ end of setq
  20.                     ) ;_ end of type
  21.               'vla-object
  22.               ) ;_ end of =
  23.            (vlax-property-available-p dict 'count)
  24.            ) ;_ end of and
  25.     (vla-get-count dict)
  26.     ) ;_ end of if
  27.   ) ;_ end of defun
  28.  
  29. (if *adn-vlr-cmd*
  30.   (progn (vlr-remove *adn-vlr-cmd*) (setq *adn-vlr-cmd* nil))
  31.   ) ;_ end of if
  32.  
  33. (if (not *adn-vlr-cmd*)
  34.   (setq *adn-vlr-cmd* (vlr-command-reactor "adn-cmd-reactor" '((:vlr-commandwillstart . _adn-vlr-cmd-start))))
  35.   ) ;_ end of if
  36.  
  37. (defun _adn-vlr-cmd-start (react cmd / datas)
  38.   (setq cmd (strcase (car cmd)))
  39.   (cond ((member cmd '("QSAVE" "SAVE" "SAVEAS"))
  40.          (if (> (setq datas (check-dict2 nil "ACAD_SCALELIST")) 100)
  41.            (progn (vla-sendcommand
  42.                     (vla-get-activedocument (vlax-get-acad-object))
  43.                     (strcat "_-scalelistedit _d" "\r" "*" "\r" "_e" "\r")
  44.                     ) ;Очистка неиспользуемых масштабов аннотаций
  45.                   (alert (strcat "ВНИМАНИЕ! Этот чертёж содержал "
  46.                                  (itoa sc)
  47.                                  " масштабов аннотаций. НЕИСПОЛЬЗУЕМЫЕ масштабы были удалены!"
  48.                                  ) ;_ end of strcat
  49.                          ) ;_ end of alert
  50.                   ) ;_ end of progn
  51.            ) ;_ end of if
  52.          (if (> (setq datas (check-dict2 nil "ACAD_DGNLINESTYLECOMP")) 10000)
  53.            (alert (strcat "ВНИМАНИЕ! Этот чертёж содержит " (itoa datas) " объектов DGN. Необходима очистка!"))
  54.            ) ;_ end of if
  55.          )
  56.         ) ;_ end of cond
  57.   ) ;_ end of defun
P.P.S. Будь время и возможность, я бы попробовал вообще выдавать запрос - вычищать сразу DgnLs или нет. Вообще говоря, вариантов тут тьма, вплоть до хранения соответствующих настроек в реестре ;)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
функцию определения количества записей символьной таблицы
То есть? Уточни, плиз.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
То есть? Уточни, плиз.
Я думаю имеется в вижу таблица слоёв, блоков, типов линий, зарегистрированных приложений и т.д.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
Ну, количество записей в этих таблицах не показатель ИМХО. Текстовые / размерные / табличные стили - да, можно, в принципе, прошерстить. Но информировать о превышении какого-то предельного числа, не предлагая ничего взамен - немного неразумно. А проходить по всей базе чертежа, исправляя "кривые" элементы - это задача точно не для лиспа. Мультилинии и мультивыноски - аналогично. Блоки? Количество описаний блоков еще ни о чем не говорит.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Я не забил и не забыл, просто работы была тьма.
В твоем коде ты получишь бесконечный цикл, скорее всего
Бесконечный цикл не получится, потому что _qsave стоит внутри (if (> sc 100) ..). После очистки масштабов происходит сохранение и во второй раз условие уже не выполняется. В этом плане код как раз оттестирован. _QSAVE я добавил после того, как понял, что команда vla-sendcommand выполняется уже после сохранения (и даже после alert). Единственный вариант, когда можно получить бесконечный цикл - это если кто-то реально использует больше 100 масштабов аннотаций и они не очистятся, но думаю столько никто не использует. Зато я точно буду знать, что по команде сохранения файл был не только очищен, а ещё и сохранён.
P.S. ИМХО код должен быть наподобие:
Твой код не очень сильно отличается от моего (убрал сохранение), к тому же содержит мелкий огрех. Ты переименовал sc в datas, а в (itoa sc) не поправил.
P.P.S. Будь время и возможность, я бы попробовал вообще выдавать запрос - вычищать сразу DgnLs или нет.
Собственно говоря это уже сделано, только не в реакторе, а в acaddoc.lsp. Правда диалог написан немного жёсткий, в том плане, что на него нельзя ответить "нет", только выбор варианта очистки - корректная и быстрая (удаление словаря).
Я думаю имеется в вижу таблица слоёв, блоков, типов линий, зарегистрированных приложений и т.д.
Ну примерно так :)
Ну, количество записей в этих таблицах не показатель ИМХО. Текстовые / размерные / табличные стили - да, можно, в принципе, прошерстить. Но информировать о превышении какого-то предельного числа, не предлагая ничего взамен - немного неразумно. А проходить по всей базе чертежа, исправляя "кривые" элементы - это задача точно не для лиспа. Мультилинии и мультивыноски - аналогично. Блоки? Количество описаний блоков еще ни о чем не говорит.
В общем-то я много думал над этим... Пока что эту функцию хотел использовать для подсчёта RegApp, чтобы очищать их при превышении адекватного количества. Для остального - да, большой вопрос. Но универсальность бывает очень удобна, как в случае с check-dict2, так сказать на будущее :)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
У тебя еще более интересная ошибка допущена: вместо vlr-remove поставлено vl-remove :)
Есть закон: если какая-то неприятность может случиться, она обязательно случится. Уточнение закона: такая неприятность обязательно случается в самый неподходящий момент.
Смотри, вариант 1: в файле до фига ссылок (пускай 20 шт., включая вложенные). Общий список аннотативных масштабов превышает все разумные пределы - а что делать? И тут при сохранении вываливается Fatal Error...
Или, вариант 2 - человек вызывает SAVEAS, планируя сохранить старый вариант. А тут ему: "Нна! Думал, что не сохранишь? А вот фига!". И как к коду будут относиться?

По поводу "табличных записей" - см. vla-get-textstyles, vla-get-dimstyles, потом понадобится смотреть словарь ACAD_TABLESTYLE, ACAD_MLINESTYLE и т.п.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!