Добро пожаловать в четвертую часть цикла, посвященного разработке плагинов под AutoCAD. Предыдущие статьи затрагивали общие вопросы создания плагина — а теперь, вооружившись этими знаниями, можно наконец-то перейти к главной задаче, стоящей перед пользователем AutoCAD: редактированию чертежа.
В этой статье будут разобраны самые простые операции, которые могут потребоваться разработчику: создание и размещение на чертеже графических примитивов (линия, ломаная, окружность, эллипс и круг).
public static string disclaimer = "Автор не является профессиональным разработчиком и не обладает глубокими знаниями AutoCAD. Этот пост – просто небольшой рассказ о создании плагина.";
Перед работой
Если уважаемый читатель захочет повторить изложенные примеры на своем компьютере, то для упрощения жизни стоит изучить автозагрузку плагинов. Например, можно почитать пост Namolem — там есть упоминание об этом.
Кратко изложу суть проблемы: поскольку после загрузки плагина «выгрузить» его невозможно, единственный способ запустить плагин, код которого был изменен, — это закрыть AutoCAD, затем вновь запустить его и повторно загрузить плагин. Эта пустяковая операция занимает от силы пару минут, однако уже после пятидесяти-ста повторений она начинает дико раздражать, я бы даже сказал — бесить.
Автозагрузка плагина позволяет исключить один из этапов этой процедуры, что поможет сберечь пару тысяч нервных клеток.
Линия
Добавление на чертеж линии не представляет никакого труда. Давайте это проделаем, использовав в качестве основы пример, изложенный в документации (перевод).
using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.ApplicationServices; using acad = Autodesk.AutoCAD.ApplicationServices.Application; namespace HabrPlug_Primitives { public class ClassMyAutoCADDLL { public class Commands : IExtensionApplication { // эта функция будет вызываться при выполнении в AutoCAD команды "HabrCommand" [CommandMethod("HabrCommand")] public void HabrCommand() { // получаем текущий документ и его БД Document acDoc = acad.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // начинаем транзакцию using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // открываем таблицу блоков документа BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // открываем пространство модели (Model View) - оно является одной из записей в таблице блоков документа BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // создаем линию между точками с указанными координатами Line acLine = new Line(new Point3d(25, 25, 0), new Point3d(33, 33, 0)); // устанавливаем параметры созданного объекта равными параметрам по умолчанию acLine.SetDatabaseDefaults(); // добавляем созданный объект в пространство модели acBlkTblRec.AppendEntity(acLine); // также добавляем созданный объект в транзакцию acTrans.AddNewlyCreatedDBObject(acLine, true); // фиксируем изменения acTrans.Commit(); } } // функции Initialize() и Terminate() необходимы, чтобы реализовать интерфейс IExtensionApplication public void Initialize() { } public void Terminate() { } } } }
Во-вторых, нужно добавить ссылки на библиотеки AcDbMgd.dll и AcMgd.dll и в свойствах этих ссылок запретить копирование библиотек в целевую папку проекта (установить параметр CopyLocal
в False
).
Сам код крайне прост, подробно расписывать здесь особо нечего.
Во-первых, мы начинаем транзакцию (что это и зачем нужно, рассматривалось в прошлой статье).
Во-вторых, мы открываем пространство модели (Model View
) — это, собственно, и есть наш чертеж. Более четкое определение Model View можно найти тут и там. Поскольку мы будем добавлять на чертеж новый объект, нужно запросить доступ «Чтение и запись» (OpenMode.ForWrite
).
В-третьих, мы создаем графический объект (в нашем случае — линию), указав в конструкторе необходимые параметры (в нашем случае — начальную и конечную точки).
В-четвертых, мы должны задать для объекта все свойства. В данном примере мы устанавливаем всем свойствам заданные по умолчанию значения, вызвав для этого функцию SetDatabaseDefaults()
. Скупое мужское описание этой функции можно найти в ObjectARX Reference.
В-пятых, необходимо добавить созданный объект в пространство модели (проще говоря — на чертеж). Это делается с помощью функции AppendEntity()
.
В-шестых, необходимо добавить созданный объект к транзакции, в рамках которой мы работаем. Для этого используется функция AddNewlyCreatedDBObject()
, которая уже разбиралась в предыдущей статье.
Наконец, после выполнения всех нужных нам операций мы должны зафиксировать транзакцию, вызвав метод Commit()
.
После компиляции проекта запускаем AutoCAD, загружаем наш плагин и выполняем команду «HabrCommand». Результат прост — но зато, надеюсь, понятен и предсказуем.
Если после запуска команды линия на экране так и не появилась — не спешите расстраиваться. Вместо этого убедитесь, что центр координат — точка (0;0) — находится в пределах видимой рабочей области. Кроме того, есть смысл поменять масштаб, покрутив колесом мыши.
Для начинающих пользователей AutoCAD может стать сюрпризом то, что масштабирование чертежа происходит в определенных пределах. Проще говоря, с ходу перейти от масштаба 1000% к масштабу 1% невозможно — после пары прокруток колеса мыши масштаб «упрется» в невидимый ограничитель. Чтобы продолжить масштабирование чертежа, необходимо выполнить команду REGEN в командной строке AutoCAD.
Давайте освежимся примером.
Ну и где здесь линия?)
Притворившуюся пылинкой на мониторе линию с головой выдают синий квадратик и появившееся окно свойств объекта.
Полилиния
Опять же, пример есть в документации (перевод).
[CommandMethod("HabrCommand")] public void HabrCommand() { // получаем текущий документ и его БД Document acDoc = acad.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // начинаем транзакцию using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // открываем таблицу блоков документа BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // открываем пространство модели (Model View) - оно является одной из записей в таблице блоков документа BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // создаем полилинию Polyline acPolyline = new Polyline(); // устанавливаем параметры созданного объекта равными параметрам по умолчанию acPolyline.SetDatabaseDefaults(); // добавляем к полилинии вершины acPolyline.AddVertexAt(0, new Point2d(2, 4), 0, 0, 0); acPolyline.AddVertexAt(1, new Point2d(4, 8), 0, 0, 0); acPolyline.AddVertexAt(2, new Point2d(6, 6), 0, 0, 0); acPolyline.AddVertexAt(3, new Point2d(8, 11), 0, 0, 0); // добавляем созданный объект в пространство модели acBlkTblRec.AppendEntity(acPolyline); // также добавляем созданный объект в транзакцию acTrans.AddNewlyCreatedDBObject(acPolyline, true); // фиксируем изменения acTrans.Commit(); } }
Результат:
Пояснять здесь особенно нечего. При желании с помощью добавления новых точек полилинию можно превратить в троллейбус довольно сложную геометрическую фигуру — например, звездочку…
[CommandMethod("HabrCommand")] public void HabrCommand() { // получаем текущий документ и его БД Document acDoc = acad.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // начинаем транзакцию using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // открываем таблицу блоков документа BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // открываем пространство модели (Model View) - оно является одной из записей в таблице блоков документа BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // создаем троллейбус Polyline acPolyline = new Polyline(); // устанавливаем параметры созданного троллейбуса равными параметрам по умолчанию acPolyline.SetDatabaseDefaults(); // добавляем к троллейбусу вершины acPolyline.AddVertexAt(0, new Point2d(100, 100), 0, 0, 0); acPolyline.AddVertexAt(1, new Point2d(100, 650), 0, 0, 0); acPolyline.AddVertexAt(2, new Point2d(1050, 650), 0, 0, 0); acPolyline.AddVertexAt(3, new Point2d(650, 1150), 0, 0, 0); acPolyline.AddVertexAt(4, new Point2d(1050, 650), 0, 0, 0); acPolyline.AddVertexAt(5, new Point2d(2050, 650), 0, 0, 0); acPolyline.AddVertexAt(6, new Point2d(2050, 100), 0, 0, 0); acPolyline.AddVertexAt(7, new Point2d(1950, 100), 0, 0, 0); acPolyline.AddVertexAt(8, new Point2d(1950, 400), 0, 0, 0); acPolyline.AddVertexAt(9, new Point2d(1800, 400), 0, 0, 0); acPolyline.AddVertexAt(10, new Point2d(1800, 100), 0, 0, 0); acPolyline.AddVertexAt(11, new Point2d(1950, 100), 0, 0, 0); acPolyline.AddVertexAt(12, new Point2d(1700, 100), 0, 0, 0); acPolyline.AddVertexAt(13, new Point2d(1660, 170), 0, 0, 0); acPolyline.AddVertexAt(14, new Point2d(1600, 225), 0, 0, 0); acPolyline.AddVertexAt(15, new Point2d(1500, 225), 0, 0, 0); acPolyline.AddVertexAt(16, new Point2d(1440, 170), 0, 0, 0); acPolyline.AddVertexAt(17, new Point2d(1400, 100), 0, 0, 0); acPolyline.AddVertexAt(18, new Point2d(850, 100), 0, 0, 0); acPolyline.AddVertexAt(19, new Point2d(1200, 100), 0, 0, 0); acPolyline.AddVertexAt(20, new Point2d(1200, 400), 0, 0, 0); acPolyline.AddVertexAt(21, new Point2d(1000, 400), 0, 0, 0); acPolyline.AddVertexAt(22, new Point2d(1000, 100), 0, 0, 0); acPolyline.AddVertexAt(23, new Point2d(1100, 100), 0, 0, 0); acPolyline.AddVertexAt(24, new Point2d(1100, 400), 0, 0, 0); acPolyline.AddVertexAt(25, new Point2d(1100, 100), 0, 0, 0); acPolyline.AddVertexAt(26, new Point2d(850, 100), 0, 0, 0); acPolyline.AddVertexAt(27, new Point2d(810, 170), 0, 0, 0); acPolyline.AddVertexAt(28, new Point2d(750, 225), 0, 0, 0); acPolyline.AddVertexAt(29, new Point2d(650, 225), 0, 0, 0); acPolyline.AddVertexAt(30, new Point2d(590, 170), 0, 0, 0); acPolyline.AddVertexAt(31, new Point2d(550, 100), 0, 0, 0); acPolyline.AddVertexAt(32, new Point2d(100, 100), 0, 0, 0); acPolyline.AddVertexAt(33, new Point2d(450, 100), 0, 0, 0); acPolyline.AddVertexAt(34, new Point2d(450, 400), 0, 0, 0); acPolyline.AddVertexAt(35, new Point2d(250, 400), 0, 0, 0); acPolyline.AddVertexAt(36, new Point2d(250, 100), 0, 0, 0); acPolyline.AddVertexAt(37, new Point2d(350, 100), 0, 0, 0); acPolyline.AddVertexAt(38, new Point2d(350, 400), 0, 0, 0); // добавляем созданный троллейбус в пространство модели acBlkTblRec.AppendEntity(acPolyline); // также добавляем созданный троллейбус в транзакцию acTrans.AddNewlyCreatedDBObject(acPolyline, true); // фиксируем изменения acTrans.Commit(); } }
Да, я тоже заметил, что у троллейбуса нет колес. Но окружности мы рисовать еще не умеем, а квадратные колеса… Нет, пусть уж лучше едет так.
Окружность
Рассмотрим пример добавления на чертеж окружности, прилежно перепечатанный из документации (ссылки были выше).
[CommandMethod("HabrCommand")] public void HabrCommand() { // получаем текущий документ и его БД Document acDoc = acad.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // начинаем транзакцию using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // открываем таблицу блоков документа BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // открываем пространство модели (Model View) - оно является одной из записей в таблице блоков документа BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // создаем окружность Circle acCircle = new Circle(); // устанавливаем параметры созданного объекта acCircle.SetDatabaseDefaults(); acCircle.Center = new Point3d(2.5, 3.14, 0); acCircle.Radius = 4.25; // добавляем созданный объект в пространство модели acBlkTblRec.AppendEntity(acCircle); // также добавляем созданный объект в транзакцию acTrans.AddNewlyCreatedDBObject(acCircle, true); // фиксируем изменения acTrans.Commit(); } }
Никаких сложностей с добавлением на чертеж окружности быть не должно: все, что нужно, — это установить центр и радиус.
Результат:
В частности, если в этом примере выполнить команду «HabrCommand» при большом отдалении, а затем сильно увеличить масштаб (приблизить элементы чертежа), то будет наблюдаться эффект, представленный на картинке ниже. Те, кто часто работает с AutoCAD, наверняка к такому привыкли — а вот я, впервые увидев, во что превратилась моя окружность, очень долго искал ошибку в коде и убил несколько часов, пытаясь «повысить точность отрисовки».)
Для восстановления первозданной формы окружности можно выполнить в командной строке AutoCAD команду REGEN:
Еще раз подчеркну, что такой эффект возникает исключительно при отображении. Внутри документа окружность всегда остается окружностью, кем бы она ни казалась снаружи.
Эллипс
Создание эллипса несколько отличается от создания окружности: его параметры должны быть явно указаны в конструкторе (подробности приведены здесь).
[CommandMethod("HabrCommand")] public void HabrCommand() { // получаем текущий документ и его БД Document acDoc = acad.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // начинаем транзакцию using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // открываем таблицу блоков документа BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // открываем пространство модели (Model View) - оно является одной из записей в таблице блоков документа BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // определяем параметры эллипса Point3d center = Point3d.Origin; Vector3d normal = Vector3d.ZAxis; Vector3d majorAxis = 100 * Vector3d.XAxis; double radiusRatio = 0.5; double startAng = 0.0; double endAng = Math.PI * 2; // создаем эллипс, сразу указывая его параметры Ellipse acEllipse = new Ellipse(center, normal, majorAxis, radiusRatio, startAng, endAng); // добавляем созданный объект в пространство модели acBlkTblRec.AppendEntity(acEllipse); // также добавляем созданный объект в транзакцию acTrans.AddNewlyCreatedDBObject(acEllipse, true); // фиксируем изменения acTrans.Commit(); } }
Результат (синяя линия добавлена для пояснения):
При создании эллипса мы задали ему следующие параметры:
- Центр (center) эллипса — с этим все понятно.
- Нормаль (normal) — вектор, перпендикулярный плоскости эллипса. Поскольку мы добавляем объект на плоскость XY, нормалью будет ось Z.
- Большая ось (majorAxis) — в понятиях AutoCAD это вектор с длиной, равной половине «ширины» эллипса (как синий отрезок на рисунке). В обычной математике это называется «большая полуось». В нашем примере мы задали вектор длиной 100, по направлению совпадающий с осью абсцисс.
- Радиус (radiusRatio) — определяет, насколько вытянут эллипс. В данном примере максимальная координата эллипса по оси Y составит 100 * 0.5 = 50.
- Начальный и конечный углы — определяют начальный и конечный углы отрисовки кривых. Принцип неплохо поясняет картинка ниже, которая взята отсюда).
Чтобы нарисовать всю фигуру, нужно «пробежать» полный круг, то есть 360 градусов, или 2pi (как в полярной системе координат). Если укажем меньше, получим только часть фигуры.
Point3d center = Point3d.Origin; Vector3d normal = Vector3d.ZAxis; Vector3d majorAxis = 100 * Vector3d.XAxis + 100 * Vector3d.YAxis; double radiusRatio = 0.5; double startAng = Math.PI * 0.1; double endAng = Math.PI * 1.3; Ellipse acEllipse = new Ellipse(center, normal, majorAxis, radiusRatio, startAng, endAng);
Получим следующее (линия проведена для удобства ориентирования):
Поскольку startAng
больше нуля, верхняя часть эллипса начинается не от оси, а чуть дальше. Поскольку endAng
сильно не дотягивает до 2pi, нижняя часть эллипса заканчивается значительно раньше положенного.
Наклон обеспечивается за счет задания вектора оси (majorAxis = 100 * Vector3d.XAxis + 100 * Vector3d.YAxis
). Поскольку X-компонента этого вектора по модулю равна Y-компоненте, получаем наклон 45 градусов.
Длину полуоси можно посчитать по теореме Пифагора: это корень квадратный из суммы квадратов координат X и Y. Вычислив корень квадратный из 1002 + 1002 (итого 20000), получим около 141. Общая длина эллипса, соответственно, составит примерно 282.
Круг
Для создания круга можно использовать штриховку — Hatch
(документация, перевод).
Порядок действий будет таким:
- Создаем границу штриховки. В качестве границы может выступать любая замкнутая кривая — в нашем случае это будет окружность.
- Задаем для границы штриховки необходимые свойства.
- Добавляем границу штриховки на чертеж.
- Создаем массив объектов, которые будут являться границами штриховки, и добавляем в него нашу границу.
- Создаем штриховку.
- Добавляем штриховку на чертеж.
- Задаем для штриховки необходимые свойства.
Шагов поприбавилось, но они все несложные.
[CommandMethod("HabrCommand")] public void HabrCommand() { // получаем текущий документ и его БД Document acDoc = acad.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // начинаем транзакцию using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // открываем таблицу блоков документа BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // открываем пространство модели (Model View) - оно является одной из записей в таблице блоков документа BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // 1) создаем окружность - границу штриховки Circle acCircle = new Circle(); // 2) устанавливаем параметры границы штриховки acCircle.SetDatabaseDefaults(); acCircle.Center = new Point3d(2.5, 3.14, 0); acCircle.Radius = 4.25; // 3) добавляем созданную границу штриховки в пространство модели и в транзакцию acBlkTblRec.AppendEntity(acCircle); acTrans.AddNewlyCreatedDBObject(acCircle, true); // 4) добавляем созданную границу штриховки в массив объектов-границ штриховки ObjectIdCollection acObjIdColl = new ObjectIdCollection(); acObjIdColl.Add(acCircle.ObjectId); // 5) создаем штриховку Hatch acHatch = new Hatch(); // 6) добавляем созданную штриховку в пространство модели и в транзакцию acBlkTblRec.AppendEntity(acHatch); acTrans.AddNewlyCreatedDBObject(acHatch, true); // 7) устанавливаем параметры штриховки acHatch.SetDatabaseDefaults(); acHatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID"); acHatch.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(0, 200, 0); acHatch.Associative = true; acHatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl); acHatch.EvaluateHatch(true); // фиксируем изменения acTrans.Commit(); } }
Результат:
Часть, где мы создаем границу штриховки, проблем вызывать не должна — это просто окружность, которую мы создали и поместили на чертеж. Часть, где создается и добавляется на чертеж штриховка, тоже в пояснениях не нуждается. Осталась часть, где мы задаем параметры штриховки. Остановимся на ней поподробнее.
Вначале мы вызываем функцию setDatabaseDefaults()
, которая устанавливает параметры штриховки равными параметрам по умолчанию. Назначение этой функции было рассмотрено в первом разделе.
Затем мы указываем тип штриховки с помощью функции SetHatchPattern()
. В данном случае мы хотим нарисовать обычный круг, поэтому выбираем тип SOLID
— «сплошная».
Вместо SOLID
мы могли бы указать что-то другое. Например, указав HOUND
, мы получили бы такой результат:
Помимо стандартных штриховок (HatchPatternType.PreDefined
) можно использовать и сторонние, которые предварительно были подключены к AutoCAD. Вот ссылка на пример.
После задания типа штриховки я указал ее цвет (свойство Color
) с помощью функции FromRgb(byte ref, byte blue, byte green)
.
Затем следует свойство Associative
— оно определяет, будет ли штриховка менять размер при изменении размера ее границ.
Associative = true
) при изменении границ штриховки:
Новый радиус круга — 5, штриховка растянулась под новый радиус.
А вот пример с Associative = false
:
В документации (перевод) сказано, что свойство Associative
должно быть установлено после добавления шриховки в таблицу блоков (то есть на пространство модели) и до вызова метода AppendLoop
.
Метод AppendLoop
позволяет указать внешнюю границу штриховки и принимает на вход два параметра: тип границы и массив объектов-границ штриховки. В качестве первого параметра мы указали HatchLoopTypes.Outermost
, тем самым обозначив, что хотим задать внешнюю границу штриховки. В качестве второго мы указали ранее созданный массив объектов-границ штриховки.
[CommandMethod("HabrCommand")] public void HabrCommand() { // получаем текущий документ и его БД Document acDoc = acad.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // начинаем транзакцию using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // открываем таблицу блоков документа BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // открываем пространство модели (Model View) - оно является одной из записей в таблице блоков документа BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // определяем внешнюю границу Polyline acPolyline = new Polyline(); acPolyline.SetDatabaseDefaults(); acPolyline.AddVertexAt(0, new Point2d(50, 50), 0, 0, 0); acPolyline.AddVertexAt(1, new Point2d(150, 285), 0, 0, 0); acPolyline.AddVertexAt(2, new Point2d(250, 50), 0, 0, 0); acPolyline.AddVertexAt(3, new Point2d(25, 200), 0, 0, 0); acPolyline.AddVertexAt(4, new Point2d(275, 200), 0, 0, 0); acPolyline.AddVertexAt(5, new Point2d(50, 50), 0, 0, 0); acBlkTblRec.AppendEntity(acPolyline); acTrans.AddNewlyCreatedDBObject(acPolyline, true); // определяем массив элементов-внешних границ ObjectIdCollection acObjIdColl_OUTER = new ObjectIdCollection(); acObjIdColl_OUTER.Add(acPolyline.ObjectId); // определяем внутреннюю границу Circle acCircleOut = new Circle(); acCircleOut.SetDatabaseDefaults(); acCircleOut.Center = new Point3d(150, 165, 0); acCircleOut.Radius = 25; acBlkTblRec.AppendEntity(acCircleOut); acTrans.AddNewlyCreatedDBObject(acCircleOut, true); // определяем массив элементов-внутренних границ ObjectIdCollection acObjIdColl_INNER = new ObjectIdCollection(); acObjIdColl_INNER.Add(acCircleOut.ObjectId); // определяем штриховку Hatch acHatch = new Hatch(); acBlkTblRec.AppendEntity(acHatch); acTrans.AddNewlyCreatedDBObject(acHatch, true); // определяем свойства штриховки acHatch.SetDatabaseDefaults(); acHatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID"); acHatch.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(200, 0, 0); acHatch.Associative = false; acHatch.HatchStyle = HatchStyle.Normal; // определяем внешние границы штриховки acHatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl_OUTER); // определяем внутренние границы штриховки acHatch.AppendLoop(HatchLoopTypes.Default, acObjIdColl_INNER); acHatch.EvaluateHatch(true); // фиксируем изменения acTrans.Commit(); } }
Теперь все параметры созданной штриховки определены. Чтобы штриховка смогла отобразиться на экране, AutoCAD должен выполнить необходимые расчеты. Для выполнения этих расчетов необходимо вызвать функцию EvaluateHatch
.
Все необходимые для создания штриховки действия выполнены. Мы уже добавили ее на чертеж и в транзакцию на шаге 6. Теперь осталось зафиксировать транзакцию, чтобы AutoCAD сохранил внесенные нами изменения.
DONUT <внутренний радиус> <внешний радиус> <координаты>
Вот две команды DONUT и результат их выполнения:
DONUT 0 25 50,50 DONUT 25 75 200,50
Кстати, какой круг больше — черный или белый?)
P. S.
Статья получилась довольно простой — зато, надеюсь, все понятно и доступно. AutoCAD .NET API позволяет вычерчивать и более сложные фигуры — например, дуги и сплайны — но мне с ними работать не доводилось. Информацию об этом, если придется, можно поискать в документации (перевод).
Вообще я планировал здесь же рассказать про добавление текста и создание простых блоков, но что-то и так уже прилично набежало. Так что эти вопросы будут освещены в следующей статье.
Спасибо за внимание!
Любые отзывы, замечания и пожелания приветствуются в комментариях.)
ссылка на оригинал статьи http://habrahabr.ru/post/257129/
Добавить комментарий