Источник:
http://www.cad.dp.ua/stats/dbx.php
Инструментарий ObjectARX позволяет создавать собственные объекты с помощью библиотеки ObjectDBX. В результате сборки приложения, написанного с помощью ObjectDBX, вы получаете файл с расширением .dbx, который загружается в AutoCAD аналогично .arx – файлу.
При создании собственных объектов, Вы расширяете стандартный набор примитивов (entity) Автокада, тем самым упрощая работу пользователя по добавлению тех или иных элементов чертежа. Немаловажным аргументом в пользу создания объектов является возможность возложения на них помимо графических (отображение в чертеже), еще и неграфических функций (хранение данных, упрощение анализа чертежа путем идентификации классов и.т.д). Однако, перед тем, как приступить к созданию объекта, разработчик должен ответить на вопрос, будет ли создание объекта наиболее оптимальным путем решения задачи. Так например, если в приложении необходимо реализовать добавление какого-либо точечного элемента в чертеж, и при этом не требуется хранить какие-либо дополнительные данные про этот элемент, то более простым решением задачи будет создание блока и программное добавление этого блока в чертеж. Создание объектов имеет смысл еще в том случае, если Вам необходимо реализовать в рамках одного элемента чертежа различные геометрические формы и текст, например как в стандартных объектах Dimensions (рис.1).
Рис. 1. Объекты Dimensions
Создание объектов – один из методов адаптации Автокада под отраслевые задачи. Так, например, если вы имеете дело с геоинформационными системами (ГИС), то в качестве примера объектов могут послужить условные обозначения на картах, в случае электроники – элементы микросхем, архитектуры – элементы архитектурных чертежей. Практически, все промышленные приложения, такие как Land Desktop, Architectural Desktop, Inventor обладает своими объектами.
Создание объекта можно разделить на два этапа: создание непосредственно самого объекта путем наследования нового класса от AcDbEntity либо AcDbObject и написание интерфейса для объекта, т.е. создание функций для добавления объекта в базу данных и работы с объектом (редактирование, взаимодействие с другими элементами чертежа). В данной статье рассматривается создание объектов для AutoCAD 2000-2002 (R-15) с помощью ObjectARX 2000, создание объектов для AutoCAD 2004 (R-16) c ObjectARX 2004 не значительно отличается – изменения касаются объявлений некоторых функций, которые приведены в рамках этой статьи.
Рассмотрим первый этап создания объектов - наследование. Для создания нового объекта следует выбрать пункт File – New… в редакторе Visual C++. В появившемся диалоговом окне следует выбрать ObjectARX 2000 AppWizrd. В следующем окне следует выбрать ObjectDBX (custom object definition). Также можно включить поддержку MFC, при этом будет выдано сообщение о том, что некоторые функции MFC будут недоступны, в случае, если приложение, которое загружает DBX не является MFC-хостом. Далее следует определится, от чего наследовать новый класс – от AcDbEntity или AcDbObject. Если Вы создаете не графический объект (например для хранения данных в словарях), тогда наследуйте от AcDbObject, если же Ваш объект требует графического представления в чертеже, тогда наследуйте от AcDbEntity. Для создания нового объекта следует вызвать ObjectARX Class Wizard, щелкнув на пиктограмме с изображением волшебной палочки на панели инструментов ObjectARX (рис. 2).
Рис. 2. Панель управления ObectARX.
В появившемся диалоговом окне нажмите на кнопку “Add Class…”, в результате появится окно “New Class”. В окне “New Class” заполните следующие поля: в поле “Class name” введите имя нового класса в поле “Derived from” укажите класс от которого следует наследовать новый (рекомендуется наследовать только от AcDbObject либо AcDbEntity), а поле “DFX name” укажите имя для обозначения вашего класса в DFX. Нажмите “Ok” и Вы снова вернетесь в окно “Object ARX ClassWizard”.
Для начала следует объявить переменные класса. Для этого перейдите на вкладку “Member Variables”. Для объявления новой переменной нажмите кнопку “Add variable”. В появившемся диалоговом окне введите имя переменной (поле “Var name”), выберите тип переменной из списка “Var type” и DXF-код из списка “DXF code”, нажмите Ok и объявление переменной и функций для работы с ней будут добавлены в файлы класса. Переменные в графических классах, как правило задают параметры геометрии примитива. Так, например, класс, представляющий собой окружность должен иметь, как минимум, две переменные - центр типа AcGePoint3d и радиус типа double.
Далее следует определится c тем, какие функции следует перегрузить в новом классе. Тут Ваш выбор зависит от того, насколько функциональным должен быть Ваш класс (имеется в виду возможность сохранения в файлы, редактирование с помощью различных команд, таких как ROTATE, MOVE, наличие в классе “ручек” (grips) и.т.д). Наиболее часто Вам придется перегружать следующие функции:
1. virtual Adesk::Boolean worldDraw(AcGiWorldDraw* mode);Отвечает за отображение примитива в чертеже.
2. virtual Acad::ErrorStatus getGeomExtents (AcDbExtents& extents) const;Определяет размеры примитива.
3. virtual Acad::ErrorStatus transformBy (const AcGeMatrix3d& xform);Перемещение примитива, команда MOVE.
4. virtual Acad::ErrorStatus getGripPoints( AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const;Отвечает за формирование набора “ручек” (grips).
5. virtual Acad::ErrorStatus moveGripPointsAt (const AcDbIntArray& indices, const AcGeVector3d& offset);Отвечает за перемещение “ручек” (grips).
6. virtual Acad::ErrorStatus getTransformedCopy ( const AcGeMatrix3d& xform, AcDbEntity*& ent) const;Отвечает за создание клона примитива при трансформации. Рассмотрим, реализацию этих функций.
mode->subEntityTraits().setColor(m_circolor); // устанавливаем цвет mode->geometry().circle(m_pos,m_cirrad,norm); // рисуем окружностьфункция subEntityTraits() возвращает указатель на объект класса AcGiSubEntityTraits для которого вызывается функция функция setColor, которая устанавливает цвет для всех последующих вызовов функций рисования примитивов; функция geometry() возвращает указатель на объект класса AcGiWorldGeometry, для которого вызывается функция circle, отображающая окружность. Полное описание всех функций класса AcGiSubEntityTraits Вы найдете в справке “ObjectARX Developer’s Guide” в разделе “AcGiSubEntityTraits Class”, описание функций рисования примитивов Вы найдете в разделе “AcGiGeometry Class”.
m_centr.transformBy(xform);xform - матрица перемещения, которую Автокад передает при вызове функции.
Мы рассмотрели наиболее часто перегружаемые функции. Если Вы хотите расширить функциональность Вашего класса, то также следует перегружать и остальные функции (см. раздел “Deriving from AcDbEntity” в справке “ObjectARX Developer’s Guide”).
Так, например, для того, чтобы Ваш примитив мог сохранятся в dwg-файле, необходимо перегрузить функции dwgInFields и dwgOutFields. Перед добавлением этих функций следует объявить все переменные - члены класса, тогда в функции будут автоматически добавлены операторы для сохранения и чтения этих переменных.
После того, как перегружены все необходимые функции, выполните компиляцию.
Теперь можно переходить к интерфейсной части. Интерфейсная часть – это arx-приложение, предназначенное для работы с объектом. После создания заготовки приложения с помощью ObjectARX AppWizard, выполните следующие действия: в файл stdarx.h добавьте заголовочный файл Вашего нового класса, в настройках проекта (Project -> Settings…) на вкладке Link добавьте lib-файл Вашего класса (появляется в результате компиляции dbx-проекта в папке Debug). Теперь можно создавать команды, использующие новый класс. Для работы со свойствами объекта можно написать собственный интерфейс, либо использовать Object Property Manager (OPM). Во втором случае Вам придется писать код автоматизации по средствам технологии COM, а в классе объекта перегрузить функцию getClassID (CLSID* pClsid)
Следует обратить внимание на то, что если Вы хотите передать чертеж, в котором присутствует объект нового класса, то также придется передать и dbx-файл для этого класса.
В качестве примера создание объектов смотрите следующие приложения: