(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Создание пользовательских примитивов в САПР на MultiCAD .NET API

Источник: habrahabr

Одним из главных недостатков традиционного .NET API в .dwg совместимых САПР является невозможность создания пользовательских примитивов (Custom Entities) на .NET. Пользовательские примитивы создаются на С++, для их использования в .NET необходимо создать управляемые обёртки на C++/CLI.

Технология MultiCAD .NET позволяет создавать пользовательские примитивы, не выходя за рамки управляемого кода. Помимо отсутствия промежуточных объектов на C++, в MultiCAD .NET максимально используются стандартные для .NET механизмы, как следствие нет необходимости во многих привычных для САПР программистов операциях: не нужно вручную описывать сериализацию, свойства в инспектор можно вывести без создания COM объекта и т.п.

В качестве демонстрации MultiCAD .NET мы рассмотрим пример приложения CustomObjects, содержащийся в комплекте поставки SDK. Этот пример создает пользовательский примитив, который представляет собой прямоугольную рамку с находящимся внутри текстом: 

Sample TextInBox MultiCAD .NET Entity

Чертежи, содержащие наш тестовый примитив, могут быть открыты в любой .dwg совместимой САПР. Для изменения примитива необходимо загрузить сборку, содержащую код примитива, причём во все поддерживаемые САПР платформы загружается одна и та же сборка без перекомпиляции. Технология является родной для nanoCAD, для загрузки модуля в AutoCAD требуется модуль расширения (Object Enabler). Как это работает смотрите под катом. 

Класс пользовательского примитива

Для создания нового типа примитива необходимо написать класс, наследованный от McCustomBase - базового класса для всех пользовательских примитивов. Кроме этого, для объявленного класса необходимо использовать два атрибута: 

  1. атрибут [CustomEntity] с указанием типа класса, его GUID, имени, которое будет использоваться для всех таких объектов в базе данных чертежа и локального имени,
  2. атрибут [Serializable], для того, чтобы воспользоваться стандартным механизмом сериализации в .NET Framework.

[CustomEntity(typeof(TextInBox), "1C925FA1-842B-49CD-924F-4ABF9717DB62", "TextInBox", "TextInBox Sample Entity")] [Serializable] public class TextInBox : McCustomBase { // First and second vertices of the box private Point3d _pnt1 = new Point3d(50, 50, 0); private Point3d _pnt2 = new Point3d(150, 100, 0); // Text inside the box private String _text = "Text field"; }
Теперь переопределим методы базового класса McCustomBase, которые будут использоваться для отображения геометрии, вставки объекта в чертеж, выбора и трансформации объекта.

Отображение геометрии

Для отображения объекта используется метод OnDraw(). В качестве параметра этого метода выступает объект класса GeometryBuilder, который, собственно, и будет использоваться для отрисовки пользовательского примитива.

public override void OnDraw(GeometryBuilder dc) { dc.Clear(); // Set the color to ByObject value dc.Color = McDbEntity.ByObject; // Draw box with choosen coordinates dc.DrawPolyline(new Point3d[] { _pnt1, new Point3d(_pnt1.X, _pnt2.Y, 0), _pnt2, new Point3d(_pnt2.X, _pnt1.Y, 0), _pnt1}); // Set text height dc.TextHeight = 2.5 * DbEntity.Scale; // Set text color dc.Color = Color.Blue; // Draw text at the box center dc.DrawMText(new Point3d((_pnt2.X + _pnt1.X) / 2.0, (_pnt2.Y + _pnt1.Y) / 2.0, 0), Vector3d.XAxis, Text, HorizTextAlign.Center, VertTextAlign.Center); }

Добавление объекта в чертеж, интерактивный ввод координат

Для добавления пользовательского объекта в чертеж используется метод PlaceObject(), который в нашем случае, кроме собственно операции добавления объекта в базу, будет использоваться и для интерактивного ввода координат объекта. За интерактивный ввод в MultiCAD .NET отвечает класс InputJig, содержащий необходимую нам функциональность:

  • public InputResult GetPoint(string promt) - получает точку на чертеже, выбранную пользователем, с возможностью вывода подсказки;
  • public void ExcludeObject(McObjectId ObjectId) - исключает указанный объект из привязки при указании точки на чертеже. В нашем случае мы исключим наш объект из привязки, чтобы избежать привязки к самому себе.
  • public EventHandler MouseMove - обработчик события движения мышкой. Будем его использовать для интерактивной перерисовки объекта при передвижении мыши.

Реализация метода PlaceObject() будет выглядеть следующим образом:

public override hresult PlaceObject(PlaceFlags lInsertType) { InputJig jig = new InputJig(); // Get the first box point from the jig InputResult res = jig.GetPoint("Select first point:"); if (res.Result != InputResult.ResultCode.Normal) return hresult.e_Fail; _pnt1 = res.Point; // Add the object to the database DbEntity.AddToCurrentDocument(); // Exclude the object from snap points jig.ExcludeObject(ID); // Monitoring mouse moving and interactive entity redrawing jig.MouseMove = (s, a) => {TryModify(); _pnt2 = a.Point; DbEntity.Update(); }; // Get the second box point from the jig res = jig.GetPoint("Select second point:"); if (res.Result != InputResult.ResultCode.Normal) { DbEntity.Erase(); return hresult.e_Fail; } _pnt2 = res.Point; return hresult.s_Ok; }

Редактирование и трансформация объекта

Добавим возможность модифицирования объекта и редактирования текстовой строки. Для этого потребуется переопределить следующие методы, содержащиеся в базовом классе McCustomBase:

  • public virtual List OnGetGripPoints() - получает список ручек для объекта;
  • public virtual void OnMoveGripPoints(List indexes, Vector3d offset, bool isStretch) - обработчик перемещения ручек;
  • public virtual void OnTransform(Matrix3d tfm) - определяет как должен трансформироваться объект;
  • public virtual hresult OnEdit(Point3d pnt, EditFlags lInsertType) - определяет процедуру редактирования объекта;

Ручки представляют собой специальные точки, отмеченные маркером, которые используются для трансформации объекта. Выведем ручки в угловых точках рамки, заданных пользователем:

public override List OnGetGripPoints() { List arr = new List(); arr.Add(_pnt1); arr.Add(_pnt2); return arr; }
Теперь, после выбора объекта на чертеже, в заданных точках будут отображены ручки:

image

Добавим возможность перемещения определяющих угловых точек с помощью перетаскивания ручек путем определения метода-обработчика OnMoveGripPoints():

public override void OnMoveGripPoints(List indexes, Vector3d offset, bool isStretch) { if (!TryModify()) return; if (indexes.Count == 2) { _pnt1 += offset; _pnt2 += offset; } else if (indexes.Count == 1) { if (indexes[0] == 0) _pnt1 += offset; else _pnt2 += offset; } }
Параметр indexes здесь содержит список номеров ручек, offset - вектор перемещения ручек.

Затем определим метод OnTransform() таким образом, чтобы при трансформации объекта рассчитывались новые координаты для обеих определяющих угловых точек:

public override void OnTransform(Matrix3d tfm) { //Save Undo state and set the object status to "Changed" if (!TryModify()) return; _pnt1 = _pnt1.TransformBy(tfm); _pnt2 = _pnt2.TransformBy(tfm); }
И, наконец, добавим возможность редактирования текстовой строки внутри рамки. Редактирование может осуществляться по двойному щелчку мыши на объекте или путем выбора соответствующего пункта контекстного меню. При вызове команды редактирования будет вызываться форма с текстовым полем, в котором можно вводить новое значение строки:

public override hresult OnEdit(Point3d pnt, EditFlags lInsertType) { TextInBox_Form frm = new TextInBox_Form(); frm.textBox1.Text = Text; frm.ShowDialog(); Text = frm.textBox1.Text; return hresult.s_Ok; }

image

Добавление свойств объекта в инспектор свойств

MultiCAD .NET API предоставляет возможность добавления свойств пользовательского объекта в инспектор свойств объекта, независимо от платформы, где будет открыт .dwg файл, будь то AutoCAD или nanoCAD. Это делается путем добавления для соответствующего общедоступного свойства объекта следующих атрибутов:

  • DisplayNameAttribute - определяет имя свойства, которое будет отображаться в инспекторе;
  • DescriptionAttribute - задает описание свойства;
  • CategoryAttribute - определяет имя категории, в которой будет отображаться данное свойство.

Воспользуемся этой возможностью и добавим свойство Text в палитру свойств объекта:

[DisplayName("Текстовая метка")] [Description("Описание метки")] [Category("Текстовый объект")] public String Text { get { return _text; } set { //Save Undo state and set the object status to "Changed" if (!TryModify()) return; // Set new text value _text = value; } }
После этого, значение текстовой строки нашего объекта будет отображаться в инспекторе объектов:

image

Итак, мы создали первую версию примитива, который можно вставить в чертёж формата .dwg и отредактировать несколькими привычными для пользователей САПР способами. Но жизнь на месте не стоит, и функционал примитивов приходится наращивать. В одной из следующих статей мы рассмотрим вторую версию примитива, куда мы добавим новые поля, и расскажем, какие возможности по работе с версиями примитивов предоставляет MultiCAD.NET API.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 31.07.2013 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
AutoCAD LT 2022 Commercial New Single-user ELD Annual Subscription
Quest Software. TOAD for SQL Server Xpert Edition
ABBYY FineReader 14 Standard Full
Allround Automation Direct Oracle Access Standard license
Microsoft 365 Business Standard (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование в AutoCAD
Компьютерный дизайн - Все графические редакторы
Мир OLAP и Business Intelligence: новости, статьи, обзоры
Delphi - проблемы и решения
Новые программы для Windows
 
Статьи по теме
 
Новинки каталога Download
 
Документация
 
 



    
rambler's top100 Rambler's Top100