- PVSM.RU - https://www.pvsm.ru -

Создание плагинов для AutoCAD с помощью .NET API (часть 1 – первые шаги)

Hello, Habr!

Решил рассказать о своем опыте работы с AutoCAD. Может быть, кому-то это поможет – ну или хотя бы интересным покажется.

public static string disclaimer = "Автор не является профессиональным разработчиком и не обладает глубокими знаниями AutoCAD. Этот пост – просто небольшой рассказ о начальном этапе создания плагина.";

Предыстория

Началось все достаточно просто: в очередной раз почувствовав острую нехватку денег, я решил, что пора бы уже начать их где-нибудь разыскивать. И вот после пары недель поиска на «Фрилансим [1]» обнаружилась вакансия разработчика для создания программы, взаимодействующей с AutoCAD.

Скажу сразу: до того дня общаться с AutoCAD мне не доводилось. Однако объявление содержало в себе фразу «Опыт работы не требуется», которая наполнила мою душу надеждой. Я связался с разместившим вакансию человеком и получил тестовое задание.

Для пробы предлагалось создать на чертеже пару объектов, а также вывести текст. Несколько дней я искал информацию об API и пытался подружиться с непривычной программой. В конце концов фигуры были нарисованы, текст выведен, а тестовое задание отправлено на проверку. И через несколько дней я неожиданно узнал, что принят! Чудеса, да и только.

В следующих абзацах – мои впечатления, синяки и шишки, мысли и советы (возможно, вредные). Разработка велась под AutoCAD 2010, в качестве IDE использовалась верная Visual Studio 2013 Express. Язык разработки – C#.

1. Подготовка необходимых инструментов

1.1. Собственно AutoCAD

Тут все понятно. Качайте с официального сайта [2] Autodesk, ставьте, 30 дней наслаждайтесь прекрасным инструментом. Потом узнайте цену покупки и повесьтесь. Для разработчиков действует специальная программа сайте [3], составляет от 700 долларов в год.

1.2. ObjectARX SDK – набор библиотек, необходимых для работы с AutoCAD

Последние три-четыре версии библиотек можно бесплатно скачать тут [4] после регистрации. Более ранние придется поискать – скажем, тут [5]. На всякий случай продублирую список прямо здесь – не такой уж он и длинный:

ссылки для загрузки ObjectARX SDK для версий AutoCAD 2000 – 2011

Версия SDK и ссылка для загрузки Совместимость с версиями AutoCAD
2011 [6] 2011, 2012
2010 [7] 2010, 2011, 2012
2009 [8] 2009
2008 x86 [9] 2008, 2009 x86
2008 x64 [10] 2008, 2009 x64
2007 [11] 2007, 2008, 2009 x86
2006 [12] 2006
2005 [13] 2005, 2006
2004 [14] 2004, 2005, 2006
2002 [15] 2002
2000i [16] 2000i, 2002
2000 [17] 2000, 2000i, 2002
R14 [18] R14

Лично меня в свое время очень заинтересовал вопрос обратной совместимости ObjectARX. Как-то раз заказчик спросил: «А с какими версиями AutoCAD сможет работать программа?», и мне пришлось изрядно времени потратить на поиски ответа. В целом, ответ звучит так: «Autodesk поддерживает обратную совместимость в течение трех лет». Какие версии совместимы между собой, можно посмотреть под спойлером выше.

Пока задачи перекомпилировать программу с другими библиотеками у меня не возникало. Думаю, что это хорошо: перспектива создавать отдельную версию продукта для других выпусков AutoCAD не радует совершенно.

1.3. MS Visual Studio 2013 Express

Великолепная IDE! Больше про нее и говорить-то нечего. Ссылок для скачивания масса – например, вот [19].

Можно, конечно, использовать и более ранние версии. Я начинал работу над проектом в MS Visual Studio 2010, но потом решил перейти на более современный выпуск.

1.4. Поисковик, усидчивость, здравый смысл

У меня был не такой большой опыт программирования – я привык решать простые задачи, для которых за глаза хватало средств самой платформы .NET. И первое мое знакомство с программированием под AutoCAD вышло не очень простым. Неприятной неожиданностью оказалось то, что у классов для работы с AutoCAD:

  • нет привычных всплывающих подсказок о назначении класса, свойства или метода;
  • нет подробной справки.

В итоге информацию я черпал из файлов помощи Object ARX (у меня они установлены в папку с именем C:ObjectARX 2010docs), а также из многочисленных форумов, блогов и сообществ разработчиков AutoCAD. Признаться, больше помогало последнее, чем первое. :)

В конце этой статьи приведен список ресурсов [20], на которых можно позадавать вопросы и, если повезет, получить на них ответы.

2. Создание проекта библиотеки

Первые шаги вполне внятно описаны здесь [21]. Владеющие английским могут попробовать зайти еще и сюда [22]. Правда, в материалах по последней ссылке упор сделан на Visual Basic, плюс нужно будет установить «AutoCAD .NET Wizard» – шаблон проекта для создания плагинов под AutoCAD. Люди знающие говорят, что этот шаблон сильно упрощает жизнь; я же никогда им не пользовался, поэтому скромно промолчу.

Вкратце продублирую основные этапы:

2.1. Создать проект «Библиотека классов» («Class Library»)

Если плагин предназначен для старой версии AutoCAD, то целесообразно сразу же задать в свойствах проекта версию .NET, которую будем использовать. Например, AutoCAD 2010 не может загружать плагины, созданные с использованием .NET Framework 4, поэтому я в качестве используемой версии указываю .NET Framework 3.5.

При понижении версии .NET Framework, используемой в проекте, могут появляться сообщения об ошибках. В моем случае Visual Studio ругается на отсутствие сборки «Microsoft.CSharp» – ее просто нужно исключить из ссылок (References).

2.2. Добавить ссылки на необходимые библиотеки AutoCAD .NET API

На этом пункте стоит остановиться чуть подробнее. AutoCAD .NET API включает в себя достаточно большое количество классов, которые разнесены по разным пространствам имен (namespaces). В свою очередь, эти пространства имен разнесены по нескольким контейнерам (проще говоря, DLL-файлам).

Эти DLL-файлы находятся в папке с именем inc-<наименование_архитектуры>. Так, в моем случае я добавляю ссылки на библиотеки из папки C:ObjectARX 2010inc-win32.

NB:

у меня дома установлена 32-разрядная ОС, у заказчика – 64-разрядная. Пока серьезных проблем с совместимостью не возникало. Но однажды я все же напоролся на то, что у меня функция возвращала Int32, а у заказчика – Int64. Линковщик ОЧЕНЬ расстраивался. Нужно иметь эту особенность в виду.

Первое знакомство с API у меня заключалось в лихорадочных попытках скомпилировать хоть какой-нибудь из примеров, щедро разбросанных по Сети. И что сλка характерно, компилироваться они упорно не хотели, ругаясь на неизвестные пространства имен и классы. В попытках собрать свой первый проект я с горя включил в него чуть ли не все DLL-файлы, которые шли с ObjectARX. Плохой способ – так делать не надо.

А как надо?

Ну, это вопрос не ко мне. Я только могу сказать, что в начале примеров обычно идет перечисление используемых пространств имен – скажем, так:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Windows;

То, что начинается со слова «Autodesk», – это и есть те дроиды пространства имен, которые мы ищем. Теперь осталось разыскать контейнеры, которые их содержат. Исчерпывающего перечня сопоставлений я найти не смог, поэтому все проверялось методом научного тыка. Если есть более правильный способ, было бы интересно его узнать…

А пока – вот список DLL-файлов, которые я использую в проекте, и содержащихся в них пространств имен:

Контейнер «AcMgd» (файл «AcMgd.dll»):

  • Autodesk.AutoCAD.ApplicationServices
  • Autodesk.AutoCAD.EditorInput
  • Autodesk.AutoCAD.GraphicsSystem
  • Autodesk.AutoCAD.Internal
  • Autodesk.AutoCAD.Internal.Calculator
  • Autodesk.AutoCAD.Internal.DatabaseServices
  • Autodesk.AutoCAD.Internal.Forms
  • Autodesk.AutoCAD.Internal.PreviousInput
  • Autodesk.AutoCAD.Internal.PropertyInspector
  • Autodesk.AutoCAD.Internal.Reactors
  • Autodesk.AutoCAD.Internal.Windows
  • Autodesk.AutoCAD.PlottingServices
  • Autodesk.AutoCAD.Publishing
  • Autodesk.AutoCAD.Runtime
  • Autodesk.AutoCAD.Windows
  • Autodesk.AutoCAD.Windows.Data
  • Autodesk.AutoCAD.Windows.ToolPalette

Контейнер «AcDbMgd» (файл «AcDbMgd.dll»):

  • Autodesk.AutoCAD.Colors
  • Autodesk.AutoCAD.ComponentModel
  • Autodesk.AutoCAD.DatabaseServices
  • Autodesk.AutoCAD.DatabaseServices.Filters
  • Autodesk.AutoCAD.Geometry
  • Autodesk.AutoCAD.GraphicsInterface
  • Autodesk.AutoCAD.GraphicsSystem
  • Autodesk.AutoCAD.LayerManager
  • Autodesk.AutoCAD.Runtime

Контейнер «AdWindows» (файл «AdWindows.dll»):

  • Autodesk.Internal.InfoCenter
  • Autodesk.Internal.Windows
  • Autodesk.Internal.Windows.ToolBars
  • Autodesk.Private.InfoCenter
  • Autodesk.Private.SubAwareService
  • Autodesk.Private.WebSearchService
  • Autodesk.Private.Windows
  • Autodesk.Private.Windows.ToolBars
  • Autodesk.Private.WsCommCntrLib
  • Autodesk.Windows
  • Autodesk.Windows.Common.Utilities
  • Autodesk.Windows.ToolBars

Контейнер «AcCui» (файл AcCui.dll»):

  • Autodesk.AutoCAD.Customization

NB:

имена многих классов AutoCAD .NET API совпадают с именами стандартных классов .NET, что не очень удобно. Например, если обратиться в коде к классу Application, то Visual Studio выругается на неоднозначность этого определения: класс с таким именем есть как в пространстве имен System.Windows, так и в пространстве имен Autodesk.AutoCAD.ApplicationServices. Чтобы не писать каждый раз полное имя, можно добавить в начало файла строку

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

Теперь в любом месте этого файла можно вместо Autodesk.AutoCAD.ApplicationServices.Application писать acadApp.

Есть смысл провернуть такую операцию с наиболее часто употребляемыми классами. Непременно так делайте, код будет компактнее и понятнее. Цинизм данного совета заключается в том, что к тому моменту, когда вы наконец поймете, какие же классы являются у вас наиболее часто употребляемыми, что-то менять будет уже сильно лень.

2.3. Написать код плагина

using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;

namespace MyAutoCADDll
{
    public class Commands : IExtensionApplication
    {
        // функция инициализации (выполняется при загрузке плагина)
        public void Initialize()
        {
            MessageBox.Show("Hello!");
        }

        // функция, выполняемая при выгрузке плагина
        public void Terminate()
        {
            MessageBox.Show("Goodbye!");
        }

        // эта функция будет вызываться при выполнении в AutoCAD команды «TestCommand»
        [CommandMethod("TestCommand")]
        public void MyCommand()
        {
            MessageBox.Show("Habr!");
        }
    }
}

Все очень просто. Вначале мы указываем необходимые пространства имен. Нам потребуются два.

В первом пространстве имен (System.Windows.Forms) хранится описание класса MessageBox, с помощью которого мы будем выводить сообщения. Чтобы сделать его доступным, необходимо добавить ссылку на одноименную сборку .NET.

Во втором пространстве имен (Autodesk.AutoCAD.Runtime) определены интерфейс IExtensionApplication и атрибут CommandMethod. Причем описание IExtensionApplication находится в файле AcDBMgd.dll, а описание CommandMethod – в файле AcMgd.dll, поэтому придется добавить ссылки на обе эти библиотеки.

Таким образом, всего необходимо добавить три ссылки:

Создание плагинов для AutoCAD с помощью .NET API (часть 1 – первые шаги)


Затем мы объявляем класс Commands. Именно он и будет «отправной точкой» плагина. Наш класс унаследован от интерфейса IExtensionApplication, поэтому в нем могут быть реализованы методы Initialize и Terminate. Первый из них автоматически выполняется при загрузке плагина, второй – при выгрузке.

NB:

AutoCAD не предоставляет разработчику возможность выгрузить плагин после того, как он будет загружен. Поэтому реально метод Terminate будет вызываться только в одном случае – при закрытии самого AutoCAD.

Почитать поподробнее про методы Initialize и Terminate можно тут [23] (rus) и там [24] (англ.).

Наконец, мы объявляем функцию MyCommand, которая будет реализовывать команду AutoCAD. Она обязательно должна ничего не принимать на вход и ничего не возвращать на выходе (не знаю, откуда у меня взялось это убеждение, но оно есть). Внутри этой функции можно делать все, что заблагорассудится (в пределах разумного, конечно), причем есть возможность работать как с AutoCAD .NET API, так и со стандартными классами .NET. Например, можно создать обычную форму Windows с полями ввода, отобразить ее на экране с помощью ShowModal(), а затем на основе введенных пользователем данных внести изменения в открытый в AutoCAD чертеж.

Чтобы «превратить» созданный метод в команду AutoCAD, применяется атрибут CommandMethod. В скобках после него указывается имя создаваемой команды, которое можно будет использовать непосредственно в среде AutoCAD.

После сборки этого проекта у нас получится готовый к употреблению плагин.

2.4. Загрузить созданный плагин

Нужно запустить AutoCAD и выполнить команду «NETLOAD»:

Создание плагинов для AutoCAD с помощью .NET API (часть 1 – первые шаги)


Затем в открывшемся окне указать путь к файлу плагина:

Создание плагинов для AutoCAD с помощью .NET API (часть 1 – первые шаги)


После этого плагин будет загружен в AutoCAD. Мы должны увидеть первое сообщение:

Создание плагинов для AutoCAD с помощью .NET API (часть 1 – первые шаги)


Если при загрузке плагина произошла критическая ошибка, она будет выведена в консоль AutoCAD:

Создание плагинов для AutoCAD с помощью .NET API (часть 1 – первые шаги)

Сообщения обычно понятные – помогут разобраться, если случай не сильно клинический. :)

NB:

если плагин не смог загрузиться из-за ошибки, то перед тестированием очередного (исправленного) варианта нужно закрыть и заново запустить AutoCAD. В противном случае он может отказаться загружать плагин, даже если ошибок в коде уже не будет.

Теперь, когда плагин загружен, можно выполнить нашу тестовую команду:

Создание плагинов для AutoCAD с помощью .NET API (часть 1 – первые шаги)


… и увидеть результат:

Создание плагинов для AutoCAD с помощью .NET API (часть 1 – первые шаги)

Работает. Теперь можно закрывать AutoCAD.

А как же…

Да – внимательный читатель, конечно, заметит, что при закрытии AutoCAD мы почему-то не увидим сообщения «Goodbye». Как уже говорилось выше, внутри функции «Terminate» можно сделать далеко не все. Но с ее помощью вполне получится, например, создать файл при закрытии AutoCAD.

2.5. Отладить плагин (при необходимости)

Процедура запуска плагина для отладки очень хорошо расписана в этом посте [25] Tepliuk [26].

Финал

Ну что же – для первого раза достаточно. Осталось привести обещанные ссылки. В посте [21] Namolem [27] и посте [28] n00buK [29] уже приведен большой объем источников; часть из них я продублирую здесь.

  1. http://adn-cis.org/forum/ [30] (rus) – форум Сообщества программистов Autodesk в СНГ. Один из лучших русскоязычных ресурсов среди всех мною встреченных в 2013-2014 годах. Сам я туда прихожу за советом, когда совсем припекает, – и не было пока случая, чтобы мне не помогли. Хотя я, конечно, стараюсь особо не злоупотреблять.
  2. http://forums.autodesk.com/t5/russkoe-soobshchestvo/bd-p/392 [31] (rus) – официальные форумы Autodesk – раздел русского сообщества. Можно позадавать вопросы.
  3. http://forums.autodesk.com/t5/net/bd-p/152 [32] (англ.) – официальные форумы Autodesk – раздел, посвященный .NET API. Тоже можно задать вопрос – правда, его могут и проигнорировать.
  4. http://through-the-interface.typepad.com [33] (англ.) – блог, который ведет Kean Walmsley, один из ведущих экспертов в разработке под AutoCAD. Ценнейший ресурс. Можно попробовать что-нибудь спросить у самого хозяина блога – и даже получить ответ, если тот будет в настроении. Впрочем, неинтересные (и простые) вопросы Kean часто игнорирует – или же предлагает вопрошающему поискать решение на официальном форуме (см. рис. 1).
  5. http://adndevblog.typepad.com [34] (англ.) – коллективный блог разработчиков из ADN. Порой бывает полезен.
  6. http://www.theswamp.org/index.php [35] (англ.) – еще один форум со множеством примеров и решений.

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

  • работа с лентой (Ribbon);
  • работа со слоями;
  • работа с динамическими блоками;
  • реализация пользовательского ввода;
  • взаимодействие плагина с внешним приложением.

Спасибо за внимание!

Автор: lostpassword

Источник [36]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/cad-cam/68996

Ссылки в тексте:

[1] Фрилансим: http://freelansim.ru/

[2] официального сайта: http://www.autodesk.ru/products/autocad/free-trial

[3] сайте: http://www.autodesk.ru/adsk/servlet/index?id=22740266&siteID=871736

[4] тут: http://www.objectarx.com/

[5] тут: http://forums.autodesk.com/t5/programmirovanie-objectarx-arx/objectarx-sdk-starye-i-novye-versii/m-p/2923492#M47

[6] 2011: http://download.autodesk.com/esd/objectarx/2011/ObjectARX_2011_Win_64_and_32Bit.exe

[7] 2010: http://download.autodesk.com/akdlm/esd/dlm/objectarx/ObjectARX_2010_Win_64_and_32Bit.exe

[8] 2009: http://download.autodesk.com/esd/objectarx/2009/ObjectARX_2009_Win_64_and_32Bit.exe

[9] 2008 x86: http://download.autodesk.com/esd/objectarx/2008/ObjectARX_2008_32Bit.exe

[10] 2008 x64: http://download.autodesk.com/esd/objectarx/2008/ObjectARX_2008_64Bit.exe

[11] 2007: http://download.autodesk.com/esd/objectarx/2007/Arx_All.exe

[12] 2006: http://download.autodesk.com/WebPub/autocad/oarx2006/Arx_All.exe

[13] 2005: http://download.autodesk.com/WebPub/Developer/autocad/Arx_All2005.exe

[14] 2004: http://download.autodesk.com/WebPub/autocad/oarx/arx_sdk.exe

[15] 2002: http://download.autodesk.com/pub/objectarx/objectarx_2002/K030.arx.plus.all.zip

[16] 2000i: http://download.autodesk.com/pub/objectarx/acad2000i/objectarx.exe

[17] 2000: http://download.autodesk.com/ProdSupp/autocad2000/ObjectARXSDK.exe

[18] R14: http://download.autodesk.com/Pub/developer/sdk/obarxsdk.exe

[19] вот: http://www.microsoft.com/ru-ru/download/details.aspx?id=40787

[20] список ресурсов: #References

[21] здесь: http://habrahabr.ru/post/148844/

[22] сюда: http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=18162797

[23] тут: https://sites.google.com/site/bushmansnetlaboratory/moi-zametki/iextensionapplication

[24] там: http://through-the-interface.typepad.com/through_the_interface/2006/09/initialization_.html

[25] этом посте: http://habrahabr.ru/post/164305/

[26] Tepliuk: http://habrahabr.ru/users/tepliuk/

[27] Namolem: http://habrahabr.ru/users/namolem/

[28] посте: http://habrahabr.ru/post/149546/

[29] n00buK: http://habrahabr.ru/users/n00buk/

[30] http://adn-cis.org/forum/: http://adn-cis.org/forum/

[31] http://forums.autodesk.com/t5/russkoe-soobshchestvo/bd-p/392: http://forums.autodesk.com/t5/russkoe-soobshchestvo/bd-p/392

[32] http://forums.autodesk.com/t5/net/bd-p/152: http://forums.autodesk.com/t5/net/bd-p/152

[33] http://through-the-interface.typepad.com: http://through-the-interface.typepad.com

[34] http://adndevblog.typepad.com: http://adndevblog.typepad.com

[35] http://www.theswamp.org/index.php: http://www.theswamp.org/index.php

[36] Источник: http://habrahabr.ru/post/235723/