Снова об очистке. Неочевидное, невероятное :)

Попался на форуме очень интересный файл. Вес файла 7 метров, но после первого же сохранения в ACAD2021 он получается - та-даааам! - 3 с лишним гига. Штатные (и полуштатные) средства ситуацию не меняют.

Спасибо doctorraz, он подсказал решение. Оказывается, проблема в "каких-то sort table".

Кх-м, где-то я подобное уже слышал. А, точно! Это ж что-то про сортировку элементов чертежа! В документацию не полезу, не хочу, сам разберусь - решил я. М-да...

Первое движение - поменять DRAWORDERCTL на 0. Не сработало: данные не учитываются, но никуда не деваются. Файл как весил 3 Гб плюс, так и весит.

Логично предположить, что данные могут храниться напрямую в примитиве? Наверное - но в примитиве после выполнения команды _.draworder ничего не поменялось. Значит, данные хранятся где-то еще.

Почти наугад проверил наличие ExtensionDictionary для пространства модели - и о чудо! Оно там есть! И даже содержит запись с именем AcDbSortEntTable. Так это то что нужно! Ее-то и надо сносить.

Сначала написал простенький код, который снесет только эту запись:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(defun t1 (/ adoc model dict)
  (setq adoc  (vla-get-activedocument (vlax-get-acad-object))
        model (vla-get-modelspace adoc)
  ) ;_ end of setq
  (if (equal (vla-get-hasextensiondictionary model) :vlax-true)
    (vlax-for item (vla-getextensiondictionary model)
      (if (or (not (vlax-property-available-p item 'name))
              (wcmatch (strcase (vla-get-name item)) "*SORTENT*")
          ) ;_ end of or
        (vl-catch-all-apply (function (lambda () (vla-delete item))))
      ) ;_ end of if
    ) ;_ end of vlax-for
  ) ;_ end of if
) ;_ end of defun

Потом подумал - какого черта?! Пишет что-то пользовательское приложение в подобные словари, пускай пишет. Но сносить я буду весь состав словаря!

1
2
3
4
5
6
7
8
9
10
(defun t2 (/ adoc model)
  (setq adoc  (vla-get-activedocument (vlax-get-acad-object))
        model (vla-get-modelspace adoc)
  ) ;_ end of setq
  (if (equal (vla-get-hasextensiondictionary model) :vlax-true)
    (vlax-for item (vla-getextensiondictionary (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
      (vl-catch-all-error-p (vl-catch-all-apply (function (lambda () (vla-delete item)))))
    ) ;_ end of vlax-for
  ) ;_ end of if
) ;_ end of defun

И уже ответил, уже опубликовал, я молодец... Ага, конечно. А тот факт, что аналогичные словари могут быть и на других пространствах листов, я не учел? Не учел. Описания блоков, уж так и быть, трогать не стану - там до фига всего может быть наверчено, а вот листы-то я пройду...

С листами связана приколка - пространства-то они пространства, да только необычные. К ним надо обращаться через соответствующие блоки (по крайней мере в лиспе). И тогда код становится уже наподобие:
- для очистки только таблицы порядка следования объектов:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(defun t3 (/ adoc)
  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (foreach space (cons (vla-get-modelspace adoc)
                       (mapcar
                         (function
                           (lambda (x)
                             (vla-get-block (vla-item (vla-get-layouts adoc) x))
                           ) ;_ end of lambda
                         ) ;_ end of function
                         (layoutlist)
                       ) ;_ end of mapcar
                 ) ;_ end of cons
    (if (equal (vla-get-hasextensiondictionary space) :vlax-true)
      (vlax-for item (vla-getextensiondictionary space)
        (if (or (not (vlax-property-available-p item 'name))
                (wcmatch (strcase (vla-get-name item)) "*SORTENT*")
            ) ;_ end of or
          (vl-catch-all-error-p (vl-catch-all-apply (function (lambda () (vla-delete item)))))
        ) ;_ end of if
      ) ;_ end of vlax-for
    ) ;_ end of if
  ) ;_ end of foreach
) ;_ end of defun

- для очистки всего содержимого словаря

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(defun t4 (/ adoc)
  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (foreach space (cons (vla-get-modelspace adoc)
                       (mapcar
                         (function
                           (lambda (x)
                             (vla-get-block (vla-item (vla-get-layouts adoc) x))
                           ) ;_ end of lambda
                         ) ;_ end of function
                         (layoutlist)
                       ) ;_ end of mapcar
                 ) ;_ end of cons
    (if (equal (vla-get-hasextensiondictionary space) :vlax-true)
      (vlax-for item (vla-getextensiondictionary space)
        (vl-catch-all-error-p (vl-catch-all-apply (function (lambda () (vla-delete item)))))
      ) ;_ end of vlax-for
    ) ;_ end of if
  ) ;_ end of foreach
) ;_ end of defun

Как результат - после примерно 5..7 минут очистки (включая _.purge, _.audit, удаление прокси и прочую лабуду) файл упал до примерно 800 кб. М-да, а мы еще матерились на DGN...



Комментарии

Есть 4 коммент. к “Снова об очистке. Неочевидное, невероятное :)”
  1. ElpanovEvgeniy пишет:

    Привет, Алексей! Как всегда, хорошая работа и понятный код, спасибо. От себя, лишь, хочу сказать - приходилось мне раньше делать обратную задачу - для генерируемого чертежа, т.е внутри пустышки создается большой набор геометрии, а там элементы и вайпауты. Вот тогда мне приходилось создавать эти словари с нуля и наполнять. Вот это была большая работа - разобраться со всеми зависимыми словарями и наследованием, чтоб автокад подхватил и работал как с родными...

  2. doctorraz пишет:

    Привет, Алексей!
    Еще бы понять откуда они берутся эти таблицы сортировки в таком количестве еще и не привязанные.
    Возможно какая то рукописная утилита генерит?
    PS doctorraz: два RR и одно Z))))

  3. Кулик Алексей aka kpblc пишет:

    Сорри, ник исправил.
    Пофантазировал, как могло бы быть: создать примитив и тут же ему задать порядок следования "поверх всех". Создать следующий - и снова "поверх всех". Такое даже на лиспе доступно, достаточно просто выключить головной мозг при написании плагина / софта ))

  4. doctorraz пишет:

    пробовал, создать 100500 примитивов, и еще столько жэж
    выбрать первые и заказал позади всех
    потом вторым заказал тоже самое
    часть примитивов удалил
    -очистить сорТТабл
    результат: "Удалено записей в таблице сортировки: 0"
    походу ты прав или кривой экспорт или программно они создаются

Поделитесь своим мнением


Я не робот.