понедельник, 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-инсталляторы, но не исходный код. Подробнее здесь.

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

Andrey Bushman комментирует...

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

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

Круто! ))

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

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

Andrey Bushman комментирует...

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

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

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

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

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

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

Andrey Bushman комментирует...

Отправил.

Unknown комментирует...
Этот комментарий был удален автором.
Andrey Bushman комментирует...

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

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

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

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

Andrey Bushman комментирует...

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

Andrey Bushman комментирует...

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

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

Andrey Bushman комментирует...

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

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

Андрей, здравствуйте!
Где можно взять версию Вашей программы для BricsCAD (желательно скомпилированную)?
А то исходники Вы убрали, а скомпилированные версии выложены только для Autocad.
Спасибо.

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

Андрей, здравствуйте!
Где можно взять версию Вашей программы для BricsCAD (желательно скомпилированную)?
А то исходники Вы убрали, а скомпилированные версии выложены только для Autocad.
Спасибо.

Andrey Bushman комментирует...

Добрый день, Артём. Открыл доступ к исходникам: https://bitbucket.org/Andrey-Bushman/cadproxy/wiki/Home