понедельник, 22 декабря 2014 г.

Управляемая альтернатива ExplodeAllProxy и RemoveAllProxy

В данной заметке даётся ссылка на полный (т.е. без "цензуры" того или иного форума) исходный код управляемой библиотеки, реализующей функционал, аналогичный командам ExplodeAllProxy и RemoveAllProxy от Александра Ривилиса. Обозначенный исходный код может использоваться не только в AutoCAD, но и в nanoCAD, BricsCAD, а так же в любом приложении, работающем на базе платформы Teigha.

Некоторое время назад А.Н. Ривилис опубликовал исходный код своего ARX расширения (за что я ему весьма признателен). Ознакомившись с исходниками А.Н. Ривилиса я написал схожее по функционалу .NET расширение. Код писался сразу с прицелом на то, чтобы он мог успешно компилироваться под:
  • все версии AutoCAD не старее чем 2009-я (в более старых не тестировал) 
  • nanoCAD 6.0 (и любые более новые версии)
  • BricsCAD 14.2 (и любые более новые версии)
  • любое автономное приложение, использующее в своей работе платформу Teigha.
В принципе, возможно, что код мог бы работать и в nanoCAD 5.0, но во первых, эта версия у меня отсутствует, а во вторых, потребуется, чтобы разработчики выпустили патч для nanoCAD 5.0, устраняющий баг реализации управляемой обёртки для класса OpenCloseTransaction. Для версии nanoCAD 6.0 такой патч существует. Скачать его можно, например отсюда. Кстати, без этого патча код данного расширения не сможет работать в nanoCAD 6.0, так что патч нужно устанавливать обязательно.

В ходе тестирования выяснилось, что команда rmScales аварийно завершает работу BricsCAD. Я задал вопрос в службу технической поддержки BricsCAD и достаточно оперативно получил ответ:
Я подтверждаю, что BricsCAD аварийно завершает работу в результате выполнения прилагаемого кода. Нулевой указатель передается в панель Свойств объектов (свойство "Annotative"). Проблема устранена в версии v15.1.02 и всех последующих версиях.
Аварийного завершения работы можно избежать двумя способами:
1. закрыть панель Свойств;
2. в методе GetFreeAnnotativeScaleIds() удалять все AnnotationScale объекты, кроме текущего (определен в переменной CANNOSCALE)
При дальнейшем изучении проблемы выяснилось, что AcDbDatabase::purge(AcDbObjectIdArray&) из ObjectARX не возвращает id текущего именованного масштаба (задается переменной CANNOSCALE). В то же время, этот id возвращается методом OdDbDatabase::purge(OdDbObjectIdArray&) в Teigha. Баг репорт с этой проблемой был направлен в Open Design Alliance. 

Мною были внесены предложенные изменения в исходный код метода GetFreeAnnotativeScaleIds и проблема с работой команды rmScales исчезла.
Дополнительно, обозначенный в этой заметке код был задействован мною в моём же автономном консольном exe приложении, предназначенном для программной пакетной обработки чертежей. Это приложение использует платформу Teigha 4.0. Поскольку код совместим с Teigha, то портировать его на любое др. приложение, использующее эту платформу, не должно составлять особого труда.

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

В коде определены следующие команды:
  • proxy - вывести в консоль информацию о количестве объектов ProxyEntity и ProxyObject, имеющихся в текущей базе данных чертежа.
  • xProxy - расчленить все объекты ProxyEntity имеющиеся в текущей базе данных чертежа.
  • rmProxy - удалить из текущей базы данных чертежа все объекты ProxyEntity и ProxyObject.
  • rmScales - удалить из текущей базы данных чертежа все неиспользуемые аннотативные масштабы из общего списка аннотативных масштабов.
Обозначенный код тестировался в:
  • AutoCAD 2009 SP3 x64 Enu
  • AutoCAD 2015 SP1 x64 Enu
  • nanoCAD 6.0 x64 Rus (при этом необходимо установить обновление hostdbmgd.zip)
  • BricsCAD 14.2.17 x64 Enu
  • собственное приложение, работающее на основе платформы Teigha 4.0.

Откомпилированная версия для AutoCAD 2009-2016 - здесь (см. файл readme.txt), исходники выложены в открытый доступ на BitBucket


UPD (27.06.2016) Программа переведена из категории открытой в категорию бесплатной. Отныне доступны MSI-инсталляторы, но не исходный код. Подробнее здесь.

12 комментариев:

Андрей Бушман комментирует...

Я обновил текст и исходный заметки в виду того, что получил ответ от технической поддержки BricsCAD по заданному мною вопросу. Теперь все команды работают в т.ч. и в BricsCAD.

dows комментирует...

Круто! ))

Денис Чужиков комментирует...

Очень полезное на мой взгляд решение. Давно хотелось более функционального управления прокси объектами.
Андрей, а есть скомпилированный .net файл? Я не программист и мне сложно весь код соединить в одном файле. Можно выложить ссылку на готовый файл?
В последнее время стал часто сталкиваться с ошибкой в AutoCad 2014 "Один или несколько файлов не может быть сохранено в текущем формате" иногда это происходит из-за прокси файлов. Можно ли как-то с помощью вашей разработки определить в каком именно объекте проблема?
Если вопрос не в тему то буду рад обсудить его с вами по e-Mail.

Андрей Бушман комментирует...

>Андрей, а есть скомпилированный .net файл? Я не программист и мне сложно весь код соединить в одном файле. Можно выложить ссылку на готовый файл?

Могу скомпилировать и выслать на почту. Я так понял, что нужна версия для AutoCAD 2014? И нужен адрес эл. почты, куда отправлять.

>В последнее время стал часто сталкиваться с ошибкой в AutoCad 2014 "Один или несколько файлов не может быть сохранено в текущем формате" иногда это происходит из-за прокси файлов. Можно ли как-то с помощью вашей разработки определить в каком именно объекте проблема?

Этой задачей я не занимался. Если причина в proxy, то их взрыв и уничтожение должно было бы решить проблему.

Денис Чужиков комментирует...

Спасибо что ответили. Скомпилированный файл отправьте пожалуйста на gnchdi@gmail.com. Нужна версия для AutoCad 2014.
Проблема с ошибкой в AutoCad 2014 "Один или несколько файлов не может быть сохранено в текущем формате" не всегда решается взрывом прокси. И стала она возникать именно с файлами расположенными в Dropbox с остальными всё в порядке, а те которые лежат в Dropbox очень часто подобную ошибку выдают.

Андрей Бушман комментирует...

Отправил.

Sergey Galkin комментирует...

Андрей, вышлите пожалуйста скомпилированную версию proxytools для 2016 Автокада на stargaz0r собака gmail.com - хочу попробовать удалять прокси через accoreconsole

Андрей Бушман комментирует...

Добавил в заметке ссылку на zip-файл, содержащий результат пакетной компиляции данного кода. Читать файл readme.txt. Целевые версии AutoCAD: 2009-2016.

Sergey Galkin комментирует...

Под coreconsole загрузка через загрузчик
(command "_.Netload" "drive://path//proxy.dll")
часто привод к эксепшену.

Загрузка же конкретной версии работает
(command "_.Netload" "drive://path//proxy.R19.0.dll")

Андрей Бушман комментирует...

Проверить работу под coreconsole смогу только через неделю, т.к. сейчас я в отпуске.

Андрей Бушман комментирует...

Внёс необходимые правки в исходный код и перекомпилировал приложение. Проверил работу кода в AutoCAD 2009-2016 (acad.exe) и AutoCAD 2013-2016 (accoreconsole.exe). Перезалил архив по обозначенной выше статье ссылке, содержащей откомпилированную версию приложения.

Изменения:
1. Для accoreconsole.exe добавил отдельную точку входа (см. readme.txt).
2. Обновил содержимое файла readme.txt.
3. Убрал из исходного кода использование псевдонимов для пространств имён.
4. Отредактировал и опубликовал код "точки входа".

Андрей Бушман комментирует...

5. Опубликовал исходный код файла ExtensionApplication.cs (ранее забыл это сделать).