Во-вторых, кто-то мешает прописать "специфические" типы линий в обычном lin-файле?Не получится. Эти DGN-овские типы линий не описываются стандартными типами линий AutoCAD. Если интересны детали, то вот статья: http://through-the-interface.typepad.com/through_the_interface/2012/12/purging-unwanted-dgn-linestyle-data-from-an-autocad-drawing-using-net.html
Эти DGN-овские типы линий не описываются стандартными типами линий AutoCAD.Не все DGN-овские типы линий не описываются стандартными типами линий AutoCAD. Первый же тип линий, взятый умельцами из Microstation, который я обнаружил, были обычные кресты, которые легко описать (см. вложение в моём предыдущем посте). Зачем умельцы взяли его из Microstation - сами не умели создавать и проще было взять готовый. Попался из Microstation.
Ну, во-первых, загрузка .NET-сборки из сетевого каталога не обязательно завершится успехом (если вообще завершится). Во-вторых, кто-то мешает прописать "специфические" типы линий в обычном lin-файле?Загрузка .NET-сборки из сетевого каталога работает нормально, ибо код уже оттестирован. Только вот с количеством обратных слэшей пришлось повозиться.
Загрузка .NET-сборки из сетевого каталога работает нормально, ибо код уже оттестирован.Дело не в коде, а во взаимодействии .NET Framework различных версий и Windows. Почитай: http://adn-cis.org/forum/index.php?topic=1110.msg9968#msg9968 Весьма полезные знания.
Дело не в коде, а во взаимодействии .NET Framework различных версий и Windows.Насколько я выяснил у админов, у всех пользователей поголовно стоит одинаковая Win7x64. Тестил код на работе на Win7x64 + Acad 2015, 2014. Всё работает.
Можно ли написать небольшой лисп, который бы проверял наличие DGN объектов в чертеже и в случае их присутствия выводил сообщение что-то вроде (alert "В чертеже обнаружены объекты DGN")?Небольшим он не получится. Да и на лиспе врядли это реализуемо. Смысл в том, что для того, чтобы уточнить есть и нет в чертеже "объекты DGN" нужно просканировать весь чертеж (ну или как минимум до первого "объекта DGN").
Если установить proxynotice = 1, то сам AutoCAD будет оповещать об этих (и других) прокси-объектах.Это прокси-объекты только в старых версиях AutoCAD, в которых объектов DGN небыло (или как минимум DEMANDLOAD в 0 - но так никто работать не сможет). А в нормальном виде это объекты AcDbDgnLS* (там целое семейство классов).
На небольших файлах он отрабатывает быстро, а на файле объёмом 25Мб уже минут 20 жду когда же вылезет окошко с количеством DGN объектов...А зачем нужно знать точное количество? Скажем если их больше 100 (значение можешь сам прикинуть) то прекращать подсчет и выдавать сообщение.
А зачем нужно знать точное количество? Скажем если их больше 100 (значение можешь сам прикинуть) то прекращать подсчет и выдавать сообщение.Логично. Что-то я про это не подумал. Спасибо большое за мысль :). Попробую поправить код на лиспе. Просто я лисп практически не знаю, пишу по примерам из других лисп программ.
Как вариант - во вложенииО, Алексей, наконец-то :) То что нужно! Спасибо огромное! :)
Да там вроде ничего такого сверхАлексей, для тех кто постоянно пишет на лиспе - да, а для того, кто этот лисп изучал 17 лет назад в институте и больше с ним не сталкивался - ну сам понимаешь :)
Добавлю: если будет предоставлен образец с тысячами (или десятками тысяч) подобных записей, возможно, появится вариант другого решения. У меня подобных файлов нет - и уже очень давно.
У меня есть сомнение в том, что алгоритм Алексея будет работать достаточно быстро. Мне кажется, что ActiveX тут не поможет и нужен другой подход через чистый AutoLISP. Интересно было бы, что бы ты проверил на своём 25Мб-ном файле, если у тебя еще остался оригинал.Код отрабатывает мгновенно :) То что нужно! Количество записей словаря acad_dgnlinestylecomp в этом 25-Мб файле - 398993.
Ну, в принципе, можно сделать и многотомный архивБыла такая мысль, но это тогда в двух сообщениях только. Первая часть в предыдущем посте.
Да, можно подставить любой словарь - хоть масштабы, хоть фильтры слоев, хоть что. Имя только менять - и все.Алексей, я имел ввиду, что не мог бы ты сам подкорректировать код на лиспе, чтобы в функцию передавать имя словаря, а функция возвращала бы количество записей :)
Код отрабатывает мгновенно :) То что нужно! Количество записей словаря acad_dgnlinestylecomp в этом 25-Мб файле - 398993.Отлично. Значит я ошибался.
Насчет "используемые-неиспользуемые": не уверен, что это легко реализуемо. Можно попытаться, конечно, удалять объект, и, если это удалось, тут же его восстанавливать - но мне такой подход не нравится на интуитивном уровне.А если так:
"Сохранить копию" - куда?Создать пользовательский словарь и туда... А потом обратно и удалить пользовательский словарь. Прошу сильно не пинать за идею...
либо вообще втихаря все сносилДумаю не стоит этого делать.
если это вообще реализуемо и не слишком медленно будет работатьЭто нереализуемо на лиспе. А на ObjectARX или .NET реализуемо, но будет работать слишком долго на файлах типа вашего 25Мбайтного мусора и соотвественно не имеет смысла - в автозагрузку такую проверку ни в коем случае ставить нельзя.
По "PrePurge" я смогу реализовать только вариант "по состоянию на последнее сохранение", не больше.Как ты собираешься на лиспе подсчитывать используемость или неиспользуемость элементов словаря в лиспе? ;)
А на ObjectARX или .NET реализуемо, но будет работать слишком долго на файлах типа вашего 25Мбайтного мусора и соотвественно не имеет смысла - в автозагрузку такую проверку ни в коем случае ставить нельзя.Возможно. Всё будет зависеть от того, сможет ли Алексей вообще реализовать эту идею и с какой скоростью это будет работать. К тому же такую проверку планируется применять не ко всем словарям сразу, а к отдельным и только после тестирования на пачке файлов. Для объектов DGN и ScaleList на данном этапе вполне достаточно проверки полного количества записей словаря.
Всё будет зависеть от того, сможет ли Алексей вообще реализовать эту идею и с какой скоростью это будет работать.Я поясню почему я считаю, что на лиспе это принципиально невозможно. Для того, чтобы определить, что какой-то из объектов словаря используется в чертеже необходимо выполнить проверку не ссылается ли каждый из объектов чертежа на выбранный объект. Для этой цели в лиспе нет средств. Но даже если бы это удалось, то пришлось бы для каждого из объектов словаря сканировать весь чертеж. Представь себе, что у тебя в словаре всего лишь 1000 объектов и в чертеже вообще больше ничего нет (в действительности есть еще хотябы 1000 объектов - слои, типы линий, визуальные стили и т.д. и т.п.). Так вот такая проверка уже будет порядка 1000000 итераций. А если это как в твоём примере > 300000 объектов в словаре, то итераций будет 90000000000 !!!
Я собираюсь скопировать текущий файл в %temp% (возможно, с новым именем) и открыть через ObjectDBX. Поудалять данные для указанных словарей и вернуть разницу. Потом закрыть файл dwg и удалить его. Надеюсь, сработает нормальноТак ты же удалишь таким образом и используемые элементы...
Если коротко - то prePurge сделать не удалось.Не страшно, спасибо и на том что сделал :) Реально очень помог :)
Или эти методы недоступны обычными методами программирования?Эти методы недоступны в лиспе, но доступны в ObjectARX.
Так и чистится там текущий документТак и надо, чтобы чистился текущий документ :) Точнее ПреПуржился :)
Зарегистрированные приложения при подключении внешней ссылки вроде бы не импортируются.Как раз импортируются и как раз просто при подключении ссылки. Могу приложить файл, в котором около 50 тысяч НЗП, подключи его, проверь :) После удаления ссылки на файл с НЗП, эти НЗП всё равно остаются в новом файле. Только что ещё раз сам проверил. Audit такого файла выполняется очень долго.
Масштабы аннотаций ссылок можно скрыть.А какой толк от их скрытия? Нужно именно, чтобы они не переносились, иначе после переноса такой файл опять будет неимоверно грузиться в качестве ссылки.
Н-да, проверил в 2016 - действительно импортируются приложения. Сорри, косякТо есть это никак не отключаемо? И импорт МА тоже? Печаль :( Хорошую подставу в этом плане AutoDesk устроил. Получается, что НЗП и МА валятся в файл как снежный ком из других файлов. Или есть идеи как отключить импорт НЗП и МА?
Ну так что, как поступаем? Реактор на вставку ссылки? Пакетная очистка? Или еще что-то?Пакетную очистку уже проходили. Рабочих файлов в сети неимоверное количество, пока в одном месте чистишь, в другом уже намусорили, а потом и намусорили в том месте, где уже почистили :) К тому же многие из них содержат кучу ссылок и долго грузятся. В общем не вариант.
Так тебе надо чистить или просто поставить юзера в известность?В идеале бы конечно диалог с предложением почистить файл. Но если нельзя, то хотя бы окошко с предупреждением, хотя это менее эффективно.
Deleting registered application "AUDIT_I_151028172007-0".У меня такое впечатление, что кто-то бездумно удалял эти приложения из файла, а AutoCAD при AUDIT и RECOVER их восстанавливал и множил.
Deleting registered application "$RECOVER_150804115203-519".
У меня такое впечатление, что кто-то бездумно удалял эти приложения из файла, а AutoCAD при AUDIT и RECOVER их восстанавливал и множил.Ну там полно и других, даже, например, таких: Удаление зарегистрированное приложение "架空面积".
Ну там полно и других, даже, например, таких: Удаление зарегистрированное приложение "架空面积".Таких - десятки, а тех десятки тысяч.
Наверное не суть важно как они появилисьЕсли они будут продолжать появляться, то ты от них не избавишься. Нужно искать причину.
Если они будут продолжать появляться, то ты от них не избавишься. Нужно искать причину.Наверное это не совсем реально. А потом основная причина большого количества НЗП, что они импортируются при подключении ссылки. Если избавиться от этого, то тогда уже будет проще с очисткой. В новом файле человек вряд ли осознанно или неосознанно сумеет наплодить 50 тысяч НЗП.
Сугубо ИМХО: "повесить" предварительную очистку при открытии файла плюс пройтись по серверу с dwg-файлами будет значительно проще, чем выдумывать что-то еще. Ну и прописать требования к файлам, предоставляемым сторонними организациями.Вешали предварительную чистку при открытии файла. Проблема в том, что очистка от такого количества НЗП выполняется очень долго. А потом где гарантии, что после чистки человек не подключит файл с НЗП и эти НЗП опять не появятся в чищенном файле? Поэтому и появилась идея с реактором на сохранение.
Для массовой очистки зарегистрированных приложений, в том числе и в XREF:За ссылку спасибо, поизучаю на досуге.
С пакетной очисткой была ещё проблема: некоторые люди работают в Civil 3D и после пакетной очистки файлов при помощи AutoCAD, эти файлы перестали открываться в Civil 3D (fatal error), так что с пакетной чисткой надо поаккуратнее, мало ли какие проблемы вылезут.Это приложение чистит только (!!!) неиспользованные зарегистрированные приложения. В этом легко убедится на примере твоего файла НПЗ.dwg. После очистки в нём остаётся 22 приложения, которые реально используются:
Это приложение чистит только (!!!) неиспользованные зарегистрированные приложения.Ну так и мы чистили только неиспользованные зарегистрированные приложения командой (command "_.-purge" "_r" "*" "_n").
Наверняка при "чистке" убивались словари, которые использует Civil - вот и результат.Словари не трогались вроде бы...
Ну так и мы чистили только неиспользованные зарегистрированные приложения командой (command "_.-purge" "_r" "*" "_n").AutoCAD (Civil 3D) 2015 SP2? Тогда нужен еще такой Fix: https://knowledge.autodesk.com/support/autocad/downloads/caas/downloads/content/autodesk-C2-AE-autocad-C2-AE-2015-sp2-xref-hotfix.html
И ещё никто не ответил на вопрос, можно ли отключить импорт НЗП и МА при подключении ссылки?Нельзя. Это принципиальное ограничение.
P.S. Алексей, а какой командой вызывается символьная таблица?
О чем речь? Это вопрос Алексею или всё-таки мне по поводу этой картинки:Ой, Александр, извините, точно ваше сообщение было :) Спасибо большое :)
Надо?Надо, конечно :)
Кстати, такое решение не отследит программную вставку ссылки через механизм ActiveXТак может логичнее было бы сделать реактор на сохранение файла (именно перед сохранением, вроде BeginSave)? Если возможно... Тогда и не надо отслеживать, хотя не принципиально, думаю народ у нас таким вряд ли пользуется.
или при выходе из AutoCADЛиспом ты можешь отловить это, но не сможешь отказаться от выхода. Т.е. очистить уже не получится.
Так? Или еще что-то надо добавлять? Честно скажу - очень не хочется по тысяче раз переписывать один и тот же код.Алексей, в принципе всё так, только может достаточно будет реактора на сохранение файла (без реактора на ссылки), если он правильно сработает?
В принципе не сложно. Просто есть несколько вопросов (ну это как обычно):1. Ничего не делаем. Если ссылкой вставляется "загаженный" файл, то весь мусор перекочёвывает в новый файл, в котором это всё будет ловиться на этапе сохранения.
1. Если был вставлен "загаженный" файл (ссылкой или блоком) - что делаем?
2. Критическое количество "на старте" и "с момента последнего сохранения" / "с момента начала" - одинаковое или будет разное? Т.е., например, при старте количество масштабов допускается до 20, а при сохранении изменение на 10 уже не гуд.
Так вот, практически "с ножом к горлу" для масштабов аннотаций нужно выполнить (if (> (check-dict2 nil "ACAD_SCALELIST") 100) (command "_-scalelistedit" "_d" "*" "_e"))Не читаешь ты то что я пишу, а жаль. Повторюсь. Средствами lisp на этапе сохранения чертежа можно лишь известить о критическом количестве масштабов аннотаций, но нельзя прервать сохранение и выполнить команду очистки.
Не читаешь ты то что я пишу, а жаль.Александр, я читал это. Просто, как я уже написал, я натолкнулся на статью Алексея про реакторы с фразой "Если "с ножом к горлу" надо использовать командную строку (бывает такое), то следует использовать механизм vla-sendcommand для текущего документа", вот и появилась надежда ::)
Александр, я читал это. Просто, как я уже написал, я натолкнулся на статью Алексея про реакторы с фразой "Если "с ножом к горлу" надо использовать командную строку (бывает такое), то следует использовать механизм vla-sendcommand для текущего документа", вот и появилась надежда ::)Код будет запущенный SendCommand будет выполнен уже после сохранения файла. Соотвественно его придётся сохранить повторно. Если обработчик BeginSave сработал при закрытии документа, то SendCommand отправит команду неизвестно куда, и документ будет уже закрыт, так что сохранить его в очищенном виде будет невозможно.
Если Алексей скажет, что такое невозможно, значит не судьба и обойдёмся алертом...
Не уверен, что сегодня успею хоть что-то сделать...Алексей, как будет время, естественно :)
Очистка масштабов аннотаций может быть выполнена и без команд:
Код выдран "с мясом" из другого проекта. А очистка, в частности, у меня на сайте рассматривалась: http://autolisp.ru/2014/03/24/clear-dwg-at-opening/Кстати, как я и писал в этой ветке, принудительная очистка словаря AcDgnLS чревата определёнными последствиями для тех, кто умудряется использовать типы линий DGN (понимаю, что таких случаев может быть мало, но, тем не менее, я напоролся).
Код будет запущенный SendCommand будет выполнен уже после сохранения файлаАлексей же вроде написал, что можно чистить масштабы лиспом... ::)
Очистка масштабов аннотаций может быть выполнена и без команд:Алексей, этот лисп удаляет ВСЕ масштабы аннотаций, даже используемые. Так не надо. Надо именно неиспользуемые, или тогда никак, только алерт.
Алексей, этот лисп удаляет ВСЕ масштабы аннотаций, даже используемые. Так не надо. Надо именно неиспользуемые,...Снова упираемся в ограничения lisp. В нём нет средств проверки "используется/не используется". Нужно сканировать всё базу чертежа.
функцию определения количества записей символьной таблицыТо есть? Уточни, плиз.
То есть? Уточни, плиз.Я думаю имеется в вижу таблица слоёв, блоков, типов линий, зарегистрированных приложений и т.д.
Я не забил и не забыл, просто работы была тьма.Бесконечный цикл не получится, потому что _qsave стоит внутри (if (> sc 100) ..). После очистки масштабов происходит сохранение и во второй раз условие уже не выполняется. В этом плане код как раз оттестирован. _QSAVE я добавил после того, как понял, что команда vla-sendcommand выполняется уже после сохранения (и даже после alert). Единственный вариант, когда можно получить бесконечный цикл - это если кто-то реально использует больше 100 масштабов аннотаций и они не очистятся, но думаю столько никто не использует. Зато я точно буду знать, что по команде сохранения файл был не только очищен, а ещё и сохранён.
В твоем коде ты получишь бесконечный цикл, скорее всего
P.S. ИМХО код должен быть наподобие:Твой код не очень сильно отличается от моего (убрал сохранение), к тому же содержит мелкий огрех. Ты переименовал sc в datas, а в (itoa sc) не поправил.
P.P.S. Будь время и возможность, я бы попробовал вообще выдавать запрос - вычищать сразу DgnLs или нет.Собственно говоря это уже сделано, только не в реакторе, а в acaddoc.lsp. Правда диалог написан немного жёсткий, в том плане, что на него нельзя ответить "нет", только выбор варианта очистки - корректная и быстрая (удаление словаря).
Я думаю имеется в вижу таблица слоёв, блоков, типов линий, зарегистрированных приложений и т.д.Ну примерно так :)
Ну, количество записей в этих таблицах не показатель ИМХО. Текстовые / размерные / табличные стили - да, можно, в принципе, прошерстить. Но информировать о превышении какого-то предельного числа, не предлагая ничего взамен - немного неразумно. А проходить по всей базе чертежа, исправляя "кривые" элементы - это задача точно не для лиспа. Мультилинии и мультивыноски - аналогично. Блоки? Количество описаний блоков еще ни о чем не говорит.В общем-то я много думал над этим... Пока что эту функцию хотел использовать для подсчёта RegApp, чтобы очищать их при превышении адекватного количества. Для остального - да, большой вопрос. Но универсальность бывает очень удобна, как в случае с check-dict2, так сказать на будущее :)
У тебя еще более интересная ошибка допущена: вместо vlr-remove поставлено vl-removeТак это же твой кусок кода отсюда: http://adn-cis.org/forum/index.php?topic=709.msg20253#msg20253 :) Я его брал за основу :) Поправить как у тебя в последнем коде?
Смотри, вариант 1: в файле до фига ссылок (пускай 20 шт., включая вложенные). Общий список аннотативных масштабов превышает все разумные пределы - а что делать? И тут при сохранении вываливается Fatal Error...А как на такую ситуацию влияет _qsave в реакторе?
Или, вариант 2 - человек вызывает SAVEAS, планируя сохранить старый вариант. А тут ему: "Нна! Думал, что не сохранишь? А вот фига!". И как к коду будут относиться?Ну будет старый вариант, только без огромного количества масштабов :) Нечего их плодить. И опять же как _qsave в реакторе повлияет на эту ситуацию, если в реакторе уже почистились масштабы?
По поводу "табличных записей" - см. vla-get-textstyles, vla-get-dimstyles, потом понадобится смотреть словарь ACAD_TABLESTYLE, ACAD_MLINESTYLE и т.п.Ну сделай отдельную функцию только подсчёта RegApp, если не сложно :)
сделай отдельную функцию только подсчёта RegApp, если не сложноТолько их или потом опять будем добавлять функционал? Если только их - то в нужное место вставляй (setq datas (vla-get-count (vla-get-registeredapplications (vla-get-activedocument (vlax-get-acad-object))))) и обрабатывай полученный результат.
Я очепятался, а ты не проверил )))Чтобы проверить надо знать лисп :) Сейчас глянул разницу :)
Только их или потом опять будем добавлять функционал? Если только их - то в нужное место вставляй (setq datas (vla-get-count (vla-get-registeredapplications (vla-get-activedocument (vlax-get-acad-object))))) и обрабатывай полученный результат.Да пока видимо только их, поскольку только они цепляются из ссылок и не чистятся стандартным диалогом purge.
По первым прикидкам вроде работаетСпасибо. Потестирую недельки через 3, после отпуска :)
Можно ли как-нибудь отловить ответ в этом диалоге и передать его реактору на закрытие, чтобы чистить и сохранять чертёж только при ответе "Да"?В VisualLisp/AutoLisp??? Нет конечно. Тут нужны Windows hooks, на которые лисп не способен.
В VisualLisp/AutoLisp??? Нет конечно. Тут нужны Windows hooks, на которые лисп не способен.Печаль :(
Вообще-то я бы не стал в реакторах использовать команды...Алексей, твою позицию по этому вопросу я помню. Тем не менее другого способа избавиться именно от неиспользуемых масштабов и зарег. приложений, кроме как очистка командой в реакторе, не было найдено/предложено. Напомню, масштабы и зарег. прил. перетекают в текущий чертёж из ссылочного файла (при подключении ссылки). Уже хочется пнуть автодеск, чтобы они сделали возможность отключения перетекания этого барахла из ссылок.
И про очистку масштабов аннотаций тоже были подобные решения, мне кажется.Нужно чистить именно неиспользуемые масштабы и приложения. Прочитав эту ветку заново, нашёл фразу о том, что лисп на такое не способен.
Теоретически можно попытаться очистить записи в словаре ACAD_SCALELIST, но я не уверен в корректности конечного результата. Надо пробовать, а у меня сейчас другой работы многоватоТак это опять же полная очистка словаря. Вся страница 4 этой ветки посвещена тому, что на лиспе нельзя создать механизм очистки неиспользуемых элементов словаря.
Снова упираемся в ограничения lisp. В нём нет средств проверки "используется/не используется". Нужно сканировать всё базу чертежа.
P.S. На прошлой работе очистку масштабов аннотаций я повесил на "загрузку" документа. Там команды применять можно совершенно спокойно.Так на загрузке она и так у меня висит. Проблема в том, что при подключении ссылки они опять липнут и толку от того что ты их почистил при загрузке никакого :( Поэтому и пошла тема реакторов.
А если использовать vla-save? Правда, как быть с абсолютно новым файлом - еще вопрос.Так вопрос в том, что надо сохранять (да и чистить тоже) только при ответе "Да" в диалоге на закрытие. А это, как сказал Александр, только хуками ловить. Я думал, может есть реактор какой-нибудь на тему этих диалоговых окон, но не нашёл.
Очистка зарегистрированных приложений:Решил потестить этот код. Сначала подумал что акад подвис. В итоге дождался. В общем код выполнялся 11 минут (для сравнения команда "purge _r" выполняется 22 секунды). Но результат заставил задуматься. С помощью ArxDbg (огромное спасибо Александру Ривилису) посмотрел содержимое RegApp Table. В принципе лисп оставил в ней почти то же самое, что и команда "purge _r", то есть вычистил неиспользуемые приложения (несколько штук не вычистил). Поэтому закралось сомнение в утверждении Александра о том, что на лиспе нельзя очищать неиспользуемые элементы.Код - Auto/Visual Lisp [Выбрать]И про очистку масштабов аннотаций тоже были подобные решения, мне кажется.
(vlax-for app (vla-get-registeredapplications (vla-get-activedocument (vlax-get-acad-object))) (vl-catch-all-apply (function (lambda () (vla-delete app)))) ) ;_ end of vlax-for