Изменение элемента на основе блоков
По мере работы над проектом и изменения элементов можно добавлять новые размеры элементов или изменять существующие размеры элементов в Конструкторе содержимого. При добавлении нового размера элемента происходит последовательное выполнение этапов процедуры. При изменении существующего размера элемента диалоговое окно со вкладками позволяет изменять только те параметры, которые нуждаются в изменении. Более подробную информацию см. в разделе «Способы создания элементов».
Для каждого размера элемента можно изменить блок 3D модели, условное обозначение, поведение элемента, видовые блоки, образец для предварительного просмотра, соединители и информацию набора свойств. Можно использовать для внесения изменений те же процедуры, которые использовались при создании элемента на основе блоков. В этом разделе приведен обзор того, как можно изменить элемент на основе блоков, и даны ссылки на соответствующие процедуры, которые можно использовать для внесения изменений.
Изменение блока 3D модели и условного обозначения
Можно изменить блок 3D модели для отдельного размера элемента. Можно отредактировать существующий блок 3D модели или создать новый блок 3D модели для одного или нескольких размеров элемента. Изменение блока 3D требует регенерации видовых блоков для размера элемента для обеспечения правильного отображения элемента на чертеже. Более подробную информацию см. в разделе «Создание 3D модели мультивидового элемента на основе блоков».
Также можно изменить условное обозначение, которое назначено размеру элемента, или прикрепить новое условное обозначение. При изменении условного обозначения выполняется его изменение для всех размеров элемента в семействе элементов. Более подробную информацию см. в разделе «Создание 2D условного обозначения для многовидового элемента на основе блоков».
Прим.: Все изменения должны быть внесены в файл DWG семейства элементов, хранящийся в каталоге элементов, до вызова Конструктора содержимого. При изменении существующего блока 3D модели следует изменять блок, хранящийся в файле DWG семейства элементов. При замене существующего блока 3D модели на новый удалите существующий блок, а затем добавьте новый блок в файл DWG семейства элементов.
Изменение поведения элемента
Можно изменить поведение элемента, определяющее, как элемент добавляется к чертежу, в том числе его тип, подтип, ключ слоя и метод вставки. Можно внести изменения в один размер элемента или в несколько размеров элемента. Более подробную информацию см. в разделе «Определение поведения элемента для многовидового элемента на основе блоков».
Прим.: Не следует вносить изменения на вкладке «Поведение» или на соответствующей странице Мастера создания параметрических элементов, если не требуется изменить поведение семейства элементов. Любые изменения, сделанные для семейства элементов, влияют на каждый размер данного элемента.
Изменение имени размера элемента и видовых блоков
Можно изменить имя размера элемента и видовые блоки, используемые для отображения размера элемента на чертеже. При изменении блока 3D модели размера элемента для обеспечения правильного отображения необходимо регенерировать видовые блоки на основе нового блока модели. Можно назначить один и тот же видовой блок нескольким направлениям взгляда, например спереди и сзади, в зависимости от симметрии элемента. Также можно вручную создать отдельные видовые блоки для размера элемента и соответствующим образом связать их с размером элемента. Для получения дополнительной информации см. раздел «Назначение имен и видов для размеров многовидового элемента на основе блоков».
Изменение образца для предварительного просмотра
Можно изменить образец для просмотра, предназначенный для размера элемента. При этом изменяется изображение для предварительного просмотра для всех размеров элемента выбранного семейства элементов. Можно регенерировать образец для просмотра на основе нового блока 3D модели или прикрепить стандартное изображение. Более подробную информацию см. в разделе «Формирование изображения предварительного просмотра многовидового элемента на основе блоков».
Изменение соединителей
Можно добавлять, удалять и редактировать соединители размера элемента. Можно изменить размер, тип и местоположение соединителя отдельного размера элемента; однако форма и область определяются связанным соединителем, заданным для семейства элементов. При удалении соединителя он удаляется для всех размеров элемента в семействе элементов. При добавлении соединителя он добавляется для всех размеров элемента в семействе элементов. Более подробную информацию см. в разделе «Добавление соединителей к многовидовому элементу на основе блоков».
Внимание: Размер и форма каждого соединителя для размера элемента могут быть разными. Однако количество соединителей для всех размеров элемента должно быть одним и тем же.
Изменение информации свойств
Можно изменить информацию свойств размера элемента. Имеется возможность добавления, удаления и редактирования пользовательских свойств для размера элемента. При добавлении пользовательского свойства выполняется его добавление к каждому размеру элемента в семействе элементов. Можно вносить необходимые изменения в значения пользовательских свойств для расширения специфицируемых данных для элементов на чертеже. Более подробную информацию см. в разделе «Добавление сведений набора свойств к многовидовому элементу на основе блоков».
Понятия, связанные с данным
- Способы создания элементов
- Изменение элементов на основе блоков с использованием Конструктора содержимого
Задачи, связанные с данной
- Создание 3D-модели для мультивидового блока MEP на основе блоков
- Создание 2D условного обозначения для многовидового элемента на основе блоков
- Определение поведения элемента для мультивидового элемента на основе блоков МЕР
- Назначение имен и видов для размеров мультивидового элемента на основе блоков
- Формирование образца для предварительного просмотра мультивидового элемента на основе блоков
- Добавление соединителей к мультивидовому элементу на основе блоков
- Добавление сведений набора свойств к мультивидовому элементу на основе блоков
Как заменить картинку в блоке автокад
Файл с расширением .mpif – это специальный установочный файл ModPlus (ModPlus Install File).
Эти файлы позволяют устанавливать и обновлять все компоненты ModPlus используя модуль автообновлений в случае, когда отсутствует доступ к сети internet или сайту modplus.org
Варианты вызова
- Меню ModPlus
- Палитра ModPlus
- Лента AutoCAD
- Командная строка: _mpBlkReplace
Значок
Описание
Плагин работает в двух режимах: Заменить выбранные – позволяет заменить все выбранные блоки на один блок-образчик; Заменить подобные – позволяет заменить все вхождения одного блока на один блок-образец. Позволяет удалить описание замененного блока из базы чертежа. По аналогии с командой «Очистить» (_PURGE). Присутствуют различные настройки
Связанные новости и статьи
Использование
Вариант работы функции [заменитьВыбранные/заменитьПодобные]:
Выбор режима работы функции
Режим «Заменить выбранные» позволяет заменить все выбранные блоки на один блок-образчик
Выберите несколько блоков для их замены:
Выбор одного или нескольких блоков. В выбор может попадать и блок-образчик
Выберите заменяющий блок:
Выбор блока-образчика, на который будут заменены блоки в предыдущем выборе
Режим «Заменить подобные» позволяет заменить все вхождения одного блока на один блок-образчик
Выберите заменяемый блок:
Выбор одного блока, все вхождения которого требуется заменить
Выберите заменяющий блок:
Выбор блока-образчика
Удаление блока из базы чертежа
Позволяет удалить описание замененного блока из базы чертежа. По аналогии с командой «Очистить» (_PURGE). Срабатывает при обоих режимах работы функции
Удалить замененные блоки из базы чертежа? [Да/Нет]:
Да — удаление описаний блока из базы чертежа; Нет — завершение работы функции
Файлы с расширением .mpif используются для установки или обновления компонентов и плагинов в случае отсутствия доступа к сети internet! Установка ModPlus производится с помощью web-установщика
Создание плагинов для AutoCAD с помощью .NET API (часть 5 – знакомство с блоками)
В пятой части цикла, посвященного разработке плагинов под AutoCAD, я расскажу про создание простых блоков и размещение их на чертеже.
public static string disclaimer = "Автор не является профессиональным разработчиком и не обладает глубокими знаниями AutoCAD. Этот пост – просто небольшой рассказ о создании плагина."
Введение
Если при работе с чертежом возникает необходимость создания однотипных объектов, то лучше всего делать это с помощью механизма блоков — именованных групп объектов, которые ведут себя как единый объект. Общие сведения о блоках можно получить здесь.
Важно уметь четко разграничивать два понятия: определение блока и вхождение блока. Подробное описание различий приведено здесь (англ.) и тут (rus). Вкратце изложу суть: когда мы создаем новый блок, AutoCAD помещает его описание в специальную таблицу блоков. Это описание называется определением блока (block definition). Определение блока существует исключительно в таблице блоков и на чертеже не отображается. Непосредственно на поле чертежа AutoCAD помещает вхождение блока (block reference) — ссылку на определение блока. При изменении определения блока все вхождения блока повторяют эти изменения. Далее в статье я иногда буду опускать первое слово («определение» или «вхождение») и писать просто «блок».
Должен сказать, что лично мне перевод «экземпляр блока» нравится гораздо больше, чем «вхождение блока». Но раз уж так написано в документации…
Как говорится, почитай отца своего, почитай мать свою и почитай руководство по эксплуатации.
В процессе общения с Autocad я сталкивался с двумя видами блоков: обычными и динамическими. Главная особенность вторых — возможность задать их элементам некоторые «настраиваемые» параметры (например, длину линии в блоке или угол ее наклона). Главный минус динамических блоков в том, что их невозможно создать средствами .NET API.
Про динамические блоки я расскажу в другой раз. А пока посмотрим, как можно работать с обычными блоками.
Создание блока вручную средствами AutoCAD
Для начала давайте создадим блок непосредственно в AutoCAD. Программирования здесь не будет — но умение создать блок вручную полезно для того, чтобы быть в состоянии хотя бы приблизительно оценить результат работы плагина. Подробности процесса — под спойлером.
Если читатель уже знаком с редактированием блоков в AutoCAD, то из этого раздела ничего нового он для себя не почерпнет.
Итак, во-первых необходимо добавить на чертеж элементы, которые мы будем объединять в блок. Для начала добавим в блок простую окружность.
В командной строке AutoCAD выполним команду CIRCLE, затем укажем центр и радиус. На чертеже появится окружность:
Выделим окружность и выполним команду BLOCK. На экране появится меню создания блока. К аналогичному результату приведет нажатие кнопки «Create» на панели «Block»:

Зададим блоку имя, выставим единицы измерения «Unitless» и снимем флажок «Open in Block Editor», после чего нажмем «ОК»:

Выбор единиц измерения позволяет задать блоку размер, который будет автоматически пересчитываться в разных системах измерения (европейской, с метрами и миллиметрами — и американской, с футами и дюймами). Если выставить значение «Unitless», то блок будет использовать те единицы измерения, которые установлены в чертеже. Я всегда выставлял значение «Unitless»; хорошо это или плохо — не знаю.
После этого AutoCAD попросит указать на чертеже точку, которая будет являться для блока базовой. Обычно в качестве этой точки задают центр блока или его нижний левый угол. Укажем в качестве базовой точки центр окружности.
Мы завершили создание блока. Первое вхождение блока будет добавлено на чертеж автоматически и заменит собой элементы, из которых был создан этот блок. Чтобы добавить на чертеж несколько вхождений созданного блока, можно использовать команду INSERT или одноименную кнопку на панели «Block»:

После выполнения команды или нажатия на кнопку на экране появится окно вставки блока:

Выбираем в списке нужный блок, нажимаем «OK», указываем точку вставки — и блок появляется на чертеже. В том, что это именно блок, можно убедиться, выделив объект и посмотрев на окно свойств:

Для редактирования блоков используется редактор, который вызывается командой BEDIT или соответствующей кнопкой на панели «Block»:

После выполнения команды или нажатия на упомянутую кнопку на экране появится окно выбора определения блока:

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

- Save Block — сохранить все сделанные изменения. После закрытия редактора блоков все вхождения блока, размещенные на чертеже, будут обновлены в соответствии с изменениями определения блока.
- Authoring Palettes — показать или скрыть окно атрибутов. Это окно пригодится при работе с динамическими блоками.
- Point — в этом выпадающем подменю находится пункт «Basepoint», с помощью которого можно задать блоку новую базовую точку.
- Close Block Editor — закрыть редактор блоков. Все несохраненные изменения будут потеряны.
На этом краткий экскурс в создание блоков в AutoCAD завершен. Можно переходить к коду. 🙂
Создание блока с помощью AutoCAD .NET API
Пример создания простого блока
Этот раздел базируется на соответствующем посте в блоге Kean Walmsley (наш пример по сравнению с первоисточником будет заметно облегчен). Мы будем создавать простейший блок, состоящий из полилинии, окружности и блока текста.
немного о колбасных обрезках
Кстати, раз уж зашел разговор про колбасные обрезки…
За последние пару лет (боже, как время-то летит!) произошло много всего хорошего. В частности, Самая Лучшая И Величайшая Компания В Мире все-таки выпустила бесплатную профессиональную версию Visual Studio.
Да, Visual Studio Community Edition занимает больше места, чем Express, и интерфейс у нее чуть посложнее — но рано или поздно у разработчика обычно возникает необходимость работы с дополнениями IDE, а они в Express-версиях не поддерживаются. Такие дела.
Пример из жизни: автор этих строк весело писал плагин в VS Express, и ничто не предвещало беды… пока не встала задача добавить программу установки (msi-файл, который создается с помощью технологии Wix). В итоге весь код инсталлятора пришлось писать в Notepad++, ежеминутно сверяясь с документацией, и компилировать вручную.
А в Visual Studio Professional можно было бы просто подключить плагин для работы с Wix и делать все прямо в IDE — с подсказками, автодополнением кода и компиляцией прямо в проекте. Можно. Было бы…
В общем, если вы работаете в компании, у которой не больше 250 ПК и годовой доход менее $1 000 000, то очень рекомендую при наличии пары-тройки лишних, бессмысленных часов жизни потратить их на установку этого продукта и далее работать с ним.
Если же бессмысленных часов в вашей жизни нет, то осознайте, что все — тлен, жизнь — боль, а влачить свое существование без установленной Visual Studio Community Edition — значит лишь увеличивать энтропию этого мира.
- Создать в таблице блоков новую запись (определение блока).
- Добавить в определение блока необходимые геометрические объекты.
- Добавить на чертеж вхождение блока.
Я уже не буду подробно останавливаться на таких мелких особенностях создания плагина, как подключение внешних ссылок, запрет CopyLocal , указание версии .NET и тому подобное — это неоднократно обговаривалось в прошлых постах цикла. В этом примере нам потребуются ссылки на библиотеки AcMgd и AcDBMgd. Кода будет немного; сразу приведу его весь, а потом разберем детали.
using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using acad = Autodesk.AutoCAD.ApplicationServices.Application; namespace HabrPlug_SimpleBlock < public class ClassMyAutoCADDLL_SimpleBlock < public class Commands : IExtensionApplication < // эта функция будет вызываться при выполнении в AutoCAD команды "HabrCommand" [CommandMethod("HabrCommand")] public void HabrCommand() < // получаем ссылки на документ и его БД Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; // поле документа "Editor" понадобится нам для вывода сообщений в окно консоли AutoCAD Editor ed = doc.Editor; // имя создаваемого блока const string blockName = "pvtBlock"; // начинаем транзакцию Transaction tr = db.TransactionManager.StartTransaction(); using (tr) < //*** // ШАГ 1 - создаем новую запись в таблице блоков //*** // открываем таблицу блоков на запись BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); // вначале проверяем, нет ли в таблице блока с таким именем // если есть - выводим сообщение об ошибке и заканчиваем выполнение команды if (bt.Has(blockName)) < ed.WriteMessage("\nA block with the name \"" + blockName + "\" already exists."); return; >// создаем новое определение блока, задаем ему имя BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; // добавляем созданное определение блока в таблицу блоков и в транзакцию, // запоминаем ID созданного определения блока (оно пригодится чуть позже) ObjectId btrId = bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true); //*** // ШАГ 2 - добавляем к созданной записи необходимые геометрические примитивы //*** // создаем полилинию Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); poly.AddVertexAt(0, new Point2d(-50, -125), 0, 0, 0); poly.AddVertexAt(1, new Point2d(-50, 105), 0, 0, 0); poly.AddVertexAt(2, new Point2d(-20, 125), 0, 0, 0); poly.AddVertexAt(3, new Point2d(20, 125), 0, 0, 0); poly.AddVertexAt(4, new Point2d(50, 105), 0, 0, 0); poly.AddVertexAt(5, new Point2d(50, -125), 0, 0, 0); poly.AddVertexAt(6, new Point2d(-50, -125), 0, 0, 0); // добавляем полилинию в определение блока и в транзакцию btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); // создаем окружность Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(0, 90, 0); cir.Radius = 15; // добавляем окружность в определение блока и в транзакцию btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); // создаем текст DBText text = new DBText(); text.Position = new Point3d(-25, -95, 0); text.Height = 35; text.TextString = "BC"; // добавляем текст в определение блока и в транзакцию btr.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); //*** // ШАГ 3 - добавляем вхождение созданного блока на чертеж //*** // открываем пространство модели на запись BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); // создаем новое вхождение блока, используя ранее сохраненный ID определения блока BlockReference br = new BlockReference(Point3d.Origin, btrId); // добавляем созданное вхождение блока на пространство модели и в транзакцию ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); // фиксируем транзакцию tr.Commit(); > > // функции Initialize() и Terminate() необходимы, чтобы реализовать интерфейс IExtensionApplication public void Initialize() < >public void Terminate() < >> > >
Поcле загрузки плагина и выполнения команды HabrCommand получим такую картинку:

Теперь давайте разбираться, что происходит в коде.
Вначале мы проводим подготовительные операции: получаем ссылки на документ, его БД и свойство Editor , задаем имя нового блока и начинаем транзакцию. Ничего нового в этом нет, кроме разве что свойства Editor .
Разыскать подробную информацию по классу Editor я с ходу не смог. Буду рад, если кто-то из более знающих людей подскажет ссылку на вменяемое описание этого класса и его методов (или хотя бы где его найти в ObjectARX Reference). В этом примере класс Editor используется только для вывода сообщения о том, что блок с таким именем уже существует в БД. В AutoCAD это сообщение выглядит так:

Внутри транзакции мы действуем по алгоритму, изложенному в начале этого подраздела.
- открываем таблицу блоков (запрашиваем доступ на запись, поскольку будем вносить изменения);
- проверяем, нет ли в таблице блока с таким именем (при попытке создать блок с именем, которое уже есть в таблице блоков, мы получим исключение eDuplicateRecordName , которое нам совершенно не нужно);
- создаем новое определение блока;
- задаем созданному определению блока имя;
- добавляем созданное определение блока в таблицу блоков и в транзакцию.
- создается необходимый объект;
- задаются свойства этого объекта;
- созданный объект добавляется в определение блока и в транзакцию.
- открывается на запись пространство модели;
- создается новое вхождение блока;
- созданное вхождение блока добавляется на пространство модели и в транзакцию.
Использование блоков, уже имеющихся в таблице блоков документа
Если в предыдущем примере выполнить команду HabrCommand, а затем удалить с чертежа появившийся блок и выполнить команду HabrCommand еще раз, то мы увидим сообщение «A block with the name „pvtBlock“ already exists», и на чертеже ничего не появится. Чтобы использовать ранее созданное определение блока, нужно узнать ObjectID этого определения. В нашем случае код можно переписать так:
Код команды:
[CommandMethod("HabrCommand")] public void HabrCommand() < // получаем ссылки на документ и его БД Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; // поле документа "Editor" понадобится нам для вывода сообщений в окно консоли AutoCAD Editor ed = doc.Editor; // имя создаваемого блока const string blockName = "pvtBlock"; // начинаем транзакцию Transaction tr = db.TransactionManager.StartTransaction(); using (tr) < //*** // ШАГ 1 - создаем новую запись в таблице блоков (или получаем ID существующей) //*** // открываем таблицу блоков на чтение BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); // проверяем, нет ли в таблице блока с таким именем // если есть - используем его ID ObjectId btrId; if (bt.Has(blockName)) < btrId = bt[blockName]; >else < // открываем таблицу блоков на запись bt.UpgradeOpen(); // создаем новое определение блока, задаем ему имя BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; // добавляем созданное определение блока в таблицу блоков, сохраняем его ID btrId = bt.Add(btr); // добавляем созданное определение блока в транзакцию tr.AddNewlyCreatedDBObject(btr, true); //*** // ШАГ 2 - добавляем к созданной записи необходимые геометрические примитивы //*** // создаем полилинию Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); poly.AddVertexAt(0, new Point2d(-50, -125), 0, 0, 0); poly.AddVertexAt(1, new Point2d(-50, 105), 0, 0, 0); poly.AddVertexAt(2, new Point2d(-20, 125), 0, 0, 0); poly.AddVertexAt(3, new Point2d(20, 125), 0, 0, 0); poly.AddVertexAt(4, new Point2d(50, 105), 0, 0, 0); poly.AddVertexAt(5, new Point2d(50, -125), 0, 0, 0); poly.AddVertexAt(6, new Point2d(-50, -125), 0, 0, 0); // добавляем полилинию в определение блока и в транзакцию btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); // создаем окружность Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(0, 90, 0); cir.Radius = 15; // добавляем окружность в определение блока и в транзакцию btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); // создаем текст DBText text = new DBText(); text.Position = new Point3d(-33, -95, 0); text.Height = 35; text.TextString = "BC"; // добавляем текст в определение блока и в транзакцию btr.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); >//*** // ШАГ 3 - добавляем вхождение созданного блока на чертеж //*** // открываем пространство модели на запись BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); // создаем новое вхождение блока, используя ранее сохраненный ID определения блока BlockReference br = new BlockReference(Point3d.Origin, btrId); // добавляем вхождение блока на пространство модели и в транзакцию ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); // фиксируем транзакцию tr.Commit(); > >
Если теперь выполнить команду HabrCommand, затем удалить с чертежа появившийся блок и повторно выполнить команду HabrCommand, то на чертеже вновь появится вхождение нашего блока. При этом нового определения блока создано не будет — плагин возьмет запись, которая уже имеется в таблице блоков.
В рассмотренном примере я для разнообразия использовал метод UpgradeOpen() , который довольно часто фигурирует в примерах и документации. Давайте разберем, как он работает.
Если в первом примере мы сразу открывали таблицу блоков на запись ( OpenMode.ForWrite ), то теперь мы вначале открываем ее только на чтение ( OpenMode.ForRead ). Этого нам хватит, чтобы просмотреть таблицу и выяснить, содержится ли в ней блок с нашим именем. Если такой блок найдется, то мы можем прочитать его ObjectID , для чего нам опять-таки хватит доступа только на чтение. Если же блока с нашим именем в таблице нет, то нам нужно его добавить, и для этого уже потребуется доступ на запись. Чтобы получить такой доступ, используется метод UpgradeOpen() — после вызова этого метода мы можем работать с таблицей блоков, как будто открыли ее с уровнем доступа OpenMode.ForWrite .
Использование UpgradeOpen() , наверное, является хорошей практикой. По крайней мере, Kean Walmsley точно так делает. Но подробных данных о том, какие сокровища и жизненные блага достаются тем, кто использует UpgradeOpen() , у меня нет. Сам я в работе эту конструкцию не использовал и особых огорчений по этому поводу не испытывал. Если кто-то может представить свою позицию по использованию UpgradeOpen() — рад буду увидеть ее в комментариях или ЛС.
Изменение позиции вставки блока
- от базовой точки, заданной в определении блока;
- от точки вставки, заданной во вхождении блока.
Картинка:

Заметим, что при создании определения блока мы нигде не задавали базовую точку в явном виде — в подобном случае AutoCAD считает, что базовой точкой является начало координат. В нашем примере «центр» фигуры был специально подобран так, чтобы он совпал с центром координат.
Изменить базовую точку определения блока можно вручную с помощью редактора блоков (как это сделать, говорилось в первом разделе поста) или средствами .NET API. В последнем случае для этой цели используется свойство Origin класса BlockTableRecord . В качестве примера давайте перенесем базовую точку определения блока в нижний левый угол. Для этого после указания имени блока зададим свойство Origin :
// задаем имя блока btr.Name = blockName; // задаем базовую точку btr.Origin = new Point3d(-50, -125, 0);
Числа -50 и -125 — это минимальные координаты нашего блока по осям X и Y соответственно (такие координаты имеет нижняя левая вершина полилинии, образующей внешнюю границу нашего блока).
Результат:

Теперь разберемся с точкой вставки блока. Она задается для каждого вхождения блока и показывает, где после вставки блока окажется его базовая точка. Это свойство задается в конструкторе класса BlockReference — например, так:
BlockReference br = new BlockReference(new Point3d(150, 150, 0), btrId);
После одновременного изменения базовой точки и точки вставки мы получим такую картину:

Блок сдвинулся опять.
Точку вставки блока можно также изменить с помощью свойства Position класса BlockReference :
BlockReference br = new BlockReference(Point3d.Origin, btrId); br.Position = new Point3d(150, 150, 0);
Эффект будет таким же, как и при задании точки непосредственно в конструкторе класса BlockReference .
Использование блоков внутри блока
Мы тут все любим блоки, так что давайте-ка добавим пару блоков в наш блок, чтобы упростить чертеж, пока мы упрощаем чертеж.
Yo dawg!

Добавление блока в определение блока не представляет никакой сложности. Главная особенность заключается в том, что если уж мы добавляем в блок не геометрический примитив, а вхождение вспомогательного блока, то нам обязательно нужно позаботиться о том, чтобы определение этого вспомогательного блока имелось в таблице блоков документа.
Код команды:
[CommandMethod("HabrCommand")] public void HabrCommand() < // получаем ссылки на документ и его БД Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; // поле документа "Editor" понадобится нам для вывода сообщений в окно консоли AutoCAD Editor ed = doc.Editor; // имя создаваемого блока const string blockName = "ltBlock"; // имя вспомогательного блока const string auxBlockName = "starBlock"; // начинаем транзакцию Transaction tr = db.TransactionManager.StartTransaction(); using (tr) < // открываем таблицу блоков на запись BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); //*** // ШАГ 0 - создаем новую запись вспомогательного блока в таблице блоков (или получаем ID существующей) //*** // проверяем, нет ли в таблице блока с таким именем // если есть - используем его ID ObjectId btrIdAux; if (bt.Has(auxBlockName)) < btrIdAux = bt[auxBlockName]; >else < // создаем новое определение блока, задаем ему имя BlockTableRecord btr = new BlockTableRecord(); btr.Name = auxBlockName; // добавляем созданное определение блока в таблицу блоков, сохраняем его ID btrIdAux = bt.Add(btr); // добавляем созданное определение блока в транзакцию tr.AddNewlyCreatedDBObject(btr, true); // создаем полилинию Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); poly.AddVertexAt(0, new Point2d(0, -6), 0, 0, 0); poly.AddVertexAt(1, new Point2d(-9, -12), 0, 0, 0); poly.AddVertexAt(2, new Point2d(-7, -2), 0, 0, 0); poly.AddVertexAt(3, new Point2d(-14, 6), 0, 0, 0); poly.AddVertexAt(4, new Point2d(-5, 6), 0, 0, 0); poly.AddVertexAt(5, new Point2d(0, 15), 0, 0, 0); poly.AddVertexAt(6, new Point2d(5, 6), 0, 0, 0); poly.AddVertexAt(7, new Point2d(14, 6), 0, 0, 0); poly.AddVertexAt(8, new Point2d(7, -2), 0, 0, 0); poly.AddVertexAt(9, new Point2d(9, -12), 0, 0, 0); poly.AddVertexAt(10, new Point2d(0, -6), 0, 0, 0); // добавляем полилинию в определение блока и в транзакцию btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); >//*** // определение вспомогательного блока создано (или получен ID этого определения) //*** //*** // ШАГ 1 - создаем новую запись в таблице блоков (или получаем ID существующей) //*** // проверяем, нет ли в таблице блока с таким именем // если есть - используем его ID ObjectId btrId; if (bt.Has(blockName)) < btrId = bt[blockName]; >else < // создаем новое определение блока, задаем ему имя BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; // добавляем созданное определение блока в таблицу блоков, сохраняем его ID btrId = bt.Add(btr); // добавляем созданное определение блока в транзакцию tr.AddNewlyCreatedDBObject(btr, true); //*** // ШАГ 2 - добавляем к созданной записи необходимые геометрические объекты //*** // создаем полилинию Polyline polyExt = new Polyline(); polyExt.SetDatabaseDefaults(); polyExt.AddVertexAt(0, new Point2d(-50, -125), 0, 0, 0); polyExt.AddVertexAt(1, new Point2d(-50, 105), 0, 0, 0); polyExt.AddVertexAt(2, new Point2d(-20, 125), 0, 0, 0); polyExt.AddVertexAt(3, new Point2d(20, 125), 0, 0, 0); polyExt.AddVertexAt(4, new Point2d(50, 105), 0, 0, 0); polyExt.AddVertexAt(5, new Point2d(50, -125), 0, 0, 0); polyExt.AddVertexAt(6, new Point2d(-50, -125), 0, 0, 0); // добавляем полилинию в определение блока и в транзакцию btr.AppendEntity(polyExt); tr.AddNewlyCreatedDBObject(polyExt, true); // создаем еще одну полилинию Polyline polyIn = new Polyline(); polyIn.SetDatabaseDefaults(); polyIn.AddVertexAt(0, new Point2d(-5, -125), 0, 0, 0); polyIn.AddVertexAt(1, new Point2d(-5, 125), 0, 0, 0); polyIn.AddVertexAt(2, new Point2d(5, 125), 0, 0, 0); polyIn.AddVertexAt(3, new Point2d(5, -125), 0, 0, 0); // добавляем вторую полилинию в определение блока и в транзакцию btr.AppendEntity(polyIn); tr.AddNewlyCreatedDBObject(polyIn, true); // создаем окружность Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(0, 90, 0); cir.Radius = 15; // добавляем окружность в определение блока и в транзакцию btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); // добавляем звездочки в определение блока и в транзакцию BlockReference starLeft = new BlockReference(new Point3d(-27, -75, 0), btrIdAux); btr.AppendEntity(starLeft); tr.AddNewlyCreatedDBObject(starLeft, true); BlockReference starRight = new BlockReference(new Point3d(27, -75, 0), btrIdAux); btr.AppendEntity(starRight); tr.AddNewlyCreatedDBObject(starRight, true); >//*** // ШАГ 3 - добавляем вхождение созданного блока на чертеж //*** // открываем пространство модели на запись BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); // создаем новое вхождение блока, используя ранее сохраненный ID определения блока BlockReference br = new BlockReference(new Point3d(150, 150, 0), btrId); // добавляем вхождение блока на пространство модели и в транзакцию ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); // фиксируем транзакцию tr.Commit(); > >
Результат:

Комментировать здесь, по большому счету, нечего: мы просто добавляем в таблицу блоков определение вспомогательного блока, а затем создаем вхождение вспомогательного блока и задаем ему координаты точки вставки.
В качестве несложного самостоятельного упражнения читателям предлагается выполнить покраску элементов блока и приведение их размеров и расположения в соответствие с Приказом № 1500.
Образец:

Зачем применять блоки?
Основных причин две… Начнем со второй.
Вторая причина
Когда на чертеже содержится большое количество однотипных объектов, использование блоков здорово сокращает размер файла чертежа. Прочувствовать это нам поможет следующий код:
Код плагина:
using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using acad = Autodesk.AutoCAD.ApplicationServices.Application; namespace HabrPlug_SimpleBlock < public class ClassMyAutoCADDLL_SimpleBlock < public class Commands : IExtensionApplication < // функция, рисующая набор геометрических фигур в заданной точке чертежа public void drawFigure(double x, double y) < // получаем ссылки на документ и его БД Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; // начинаем транзакцию Transaction tr = db.TransactionManager.StartTransaction(); using (tr) < // открываем таблицу блоков на запись BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); // открываем пространство модели на запись BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); // создаем полилинию Polyline polyExt = new Polyline(); polyExt.SetDatabaseDefaults(); polyExt.AddVertexAt(0, new Point2d(x - 50, y - 125), 0, 0, 0); polyExt.AddVertexAt(1, new Point2d(x - 50, y + 105), 0, 0, 0); polyExt.AddVertexAt(2, new Point2d(x - 20, y + 125), 0, 0, 0); polyExt.AddVertexAt(3, new Point2d(x + 20, y + 125), 0, 0, 0); polyExt.AddVertexAt(4, new Point2d(x + 50, y + 105), 0, 0, 0); polyExt.AddVertexAt(5, new Point2d(x + 50, y - 125), 0, 0, 0); polyExt.AddVertexAt(6, new Point2d(x - 50, y - 125), 0, 0, 0); // добавляем полилинию на пространство модели и в транзакцию ms.AppendEntity(polyExt); tr.AddNewlyCreatedDBObject(polyExt, true); // создаем еще полилинию Polyline polyIn = new Polyline(); polyIn.SetDatabaseDefaults(); polyIn.AddVertexAt(0, new Point2d(x - 5, y - 125), 0, 0, 0); polyIn.AddVertexAt(1, new Point2d(x - 5, y + 125), 0, 0, 0); polyIn.AddVertexAt(2, new Point2d(x + 5, y + 125), 0, 0, 0); polyIn.AddVertexAt(3, new Point2d(x + 5, y - 125), 0, 0, 0); // добавляем вторую полилинию на пространство модели и в транзакцию ms.AppendEntity(polyIn); tr.AddNewlyCreatedDBObject(polyIn, true); // создаем окружность Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(x, y + 90, 0); cir.Radius = 15; // добавляем окружность на пространство модели и в транзакцию ms.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); // создаем звездочки, добавляем их на пространство модели и в транзакцию Polyline starLeft= new Polyline(); starLeft.SetDatabaseDefaults(); starLeft.AddVertexAt(0, new Point2d(x - 27, y - 75 - 6), 0, 0, 0); starLeft.AddVertexAt(1, new Point2d(x - 27 - 9, y - 75 - 12), 0, 0, 0); starLeft.AddVertexAt(2, new Point2d(x - 27 - 7, y - 75 - 2), 0, 0, 0); starLeft.AddVertexAt(3, new Point2d(x - 27 - 14, y - 75 + 6), 0, 0, 0); starLeft.AddVertexAt(4, new Point2d(x - 27 - 5, y - 75 + 6), 0, 0, 0); starLeft.AddVertexAt(5, new Point2d(x - 27, y - 75 + 15), 0, 0, 0); starLeft.AddVertexAt(6, new Point2d(x - 27 + 5, y - 75 + 6), 0, 0, 0); starLeft.AddVertexAt(7, new Point2d(x - 27 + 14, y - 75 + 6), 0, 0, 0); starLeft.AddVertexAt(8, new Point2d(x - 27 + 7, y - 75 - 2), 0, 0, 0); starLeft.AddVertexAt(9, new Point2d(x - 27 + 9, y - 75 - 12), 0, 0, 0); starLeft.AddVertexAt(10, new Point2d(x - 27, y - 75 - 6), 0, 0, 0); ms.AppendEntity(starLeft); tr.AddNewlyCreatedDBObject(starLeft, true); Polyline starRight = new Polyline(); starRight.SetDatabaseDefaults(); starRight.AddVertexAt(0, new Point2d(x + 27, y - 75 - 6), 0, 0, 0); starRight.AddVertexAt(1, new Point2d(x + 27 - 9, y - 75 - 12), 0, 0, 0); starRight.AddVertexAt(2, new Point2d(x + 27 - 7, y - 75 - 2), 0, 0, 0); starRight.AddVertexAt(3, new Point2d(x + 27 - 14, y - 75 + 6), 0, 0, 0); starRight.AddVertexAt(4, new Point2d(x + 27 - 5, y - 75 + 6), 0, 0, 0); starRight.AddVertexAt(5, new Point2d(x + 27, y - 75 + 15), 0, 0, 0); starRight.AddVertexAt(6, new Point2d(x + 27 + 5, y - 75 + 6), 0, 0, 0); starRight.AddVertexAt(7, new Point2d(x + 27 + 14, y - 75 + 6), 0, 0, 0); starRight.AddVertexAt(8, new Point2d(x + 27 + 7, y - 75 - 2), 0, 0, 0); starRight.AddVertexAt(9, new Point2d(x + 27 + 9, y - 75 - 12), 0, 0, 0); starRight.AddVertexAt(10, new Point2d(x + 27, y - 75 - 6), 0, 0, 0); ms.AppendEntity(starRight); tr.AddNewlyCreatedDBObject(starRight, true); // фиксируем транзакцию tr.Commit(); >> // функция, рисующая блок в заданной точке чертежа public void drawBlock(double x, double y) < // получаем ссылки на документ и его БД Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; // поле документа "Editor" понадобится нам для вывода сообщений в окно сообщений AutoCAD Editor ed = doc.Editor; // имя создаваемого блока const string blockName = "ltBlock"; const string auxBlockName = "starBlock"; // начинаем транзакцию Transaction tr = db.TransactionManager.StartTransaction(); using (tr) < // открываем таблицу блоков на запись BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); //*** // ШАГ 0 - создаем новую запись вспомогательного блока в таблице блоков (или получаем ID существующей) //*** ObjectId btrIdAux; if (bt.Has(auxBlockName)) < btrIdAux = bt[auxBlockName]; >else < // создаем новое определение блока, задаем ему имя BlockTableRecord btr = new BlockTableRecord(); btr.Name = auxBlockName; // добавляем созданное определение блока в таблицу блоков, сохраняем его ID btrIdAux = bt.Add(btr); // добавляем созданное определение блока в транзакцию tr.AddNewlyCreatedDBObject(btr, true); // создаем полилинию Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); poly.AddVertexAt(0, new Point2d(0, -6), 0, 0, 0); poly.AddVertexAt(1, new Point2d(-9, -12), 0, 0, 0); poly.AddVertexAt(2, new Point2d(-7, -2), 0, 0, 0); poly.AddVertexAt(3, new Point2d(-14, 6), 0, 0, 0); poly.AddVertexAt(4, new Point2d(-5, 6), 0, 0, 0); poly.AddVertexAt(5, new Point2d(0, 15), 0, 0, 0); poly.AddVertexAt(6, new Point2d(5, 6), 0, 0, 0); poly.AddVertexAt(7, new Point2d(14, 6), 0, 0, 0); poly.AddVertexAt(8, new Point2d(7, -2), 0, 0, 0); poly.AddVertexAt(9, new Point2d(9, -12), 0, 0, 0); poly.AddVertexAt(10, new Point2d(0, -6), 0, 0, 0); // добавляем полилинию в определение блока и в транзакцию btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); >//*** // ШАГ 1 - создаем новую запись в таблице блоков (или получаем ID существующей) //*** // проверяем, нет ли в таблице блока с таким именем // если есть - используем его ID ObjectId btrId; if (bt.Has(blockName)) < btrId = bt[blockName]; >else < // создаем новое определение блока, задаем ему имя BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; // добавляем созданное определение блока в таблицу блоков, сохраняем его ID btrId = bt.Add(btr); // добавляем созданное определение блока в транзакцию tr.AddNewlyCreatedDBObject(btr, true); //*** // ШАГ 2 - добавляем к созданной записи необходимые геометрические примитивы //*** // создаем полилинию Polyline polyExt = new Polyline(); polyExt.SetDatabaseDefaults(); polyExt.AddVertexAt(0, new Point2d(-50, -125), 0, 0, 0); polyExt.AddVertexAt(1, new Point2d(-50, 105), 0, 0, 0); polyExt.AddVertexAt(2, new Point2d(-20, 125), 0, 0, 0); polyExt.AddVertexAt(3, new Point2d(20, 125), 0, 0, 0); polyExt.AddVertexAt(4, new Point2d(50, 105), 0, 0, 0); polyExt.AddVertexAt(5, new Point2d(50, -125), 0, 0, 0); polyExt.AddVertexAt(6, new Point2d(-50, -125), 0, 0, 0); // добавляем полилинию в определение блока и в транзакцию btr.AppendEntity(polyExt); tr.AddNewlyCreatedDBObject(polyExt, true); // создаем еще полилинию Polyline polyIn = new Polyline(); polyIn.SetDatabaseDefaults(); polyIn.AddVertexAt(0, new Point2d(-5, -125), 0, 0, 0); polyIn.AddVertexAt(1, new Point2d(-5, 125), 0, 0, 0); polyIn.AddVertexAt(2, new Point2d(5, 125), 0, 0, 0); polyIn.AddVertexAt(3, new Point2d(5, -125), 0, 0, 0); // добавляем вторую полилинию в определение блока и в транзакцию btr.AppendEntity(polyIn); tr.AddNewlyCreatedDBObject(polyIn, true); // создаем окружность Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(0, 90, 0); cir.Radius = 15; // добавляем окружность в определение блока и в транзакцию btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); // добавляем звездочки BlockReference starLeft = new BlockReference(new Point3d(-27, -75, 0), btrIdAux); btr.AppendEntity(starLeft); tr.AddNewlyCreatedDBObject(starLeft, true); BlockReference starRight = new BlockReference(new Point3d(27, -75, 0), btrIdAux); btr.AppendEntity(starRight); tr.AddNewlyCreatedDBObject(starRight, true); >//*** // ШАГ 3 - добавляем вхождение созданного блока на чертеж //*** // открываем пространство модели на запись BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); // создаем новое вхождение блока, используя сохраненный ранее ID определения блока BlockReference br = new BlockReference(new Point3d(x, y, 0), btrId); // добавляем вхождение блока на пространство модели и в транзакцию ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); // фиксируем транзакцию tr.Commit(); > > // эта функция будет вызываться при выполнении в AutoCAD команды "HabrCommand_DrawFigures" [CommandMethod("HabrCommand_DrawFigures")] public void HabrCommand_DrawFigures() < for (int x = 0; x < 100; x++) < for (int y = 0; y < 100; y++) < drawFigure(125 * x, 300 * y); >> > // эта функция будет вызываться при выполнении в AutoCAD команды "HabrCommand_DrawBlocks" [CommandMethod("HabrCommand_DrawBlocks")] public void HabrCommand_DrawBlocks() < for (int x = 0; x < 100; x++) < for (int y = 0; y < 100; y++) < drawBlock(125 * x, 300 * y); >> > // функции Initialize() и Terminate() необходимы, чтобы реализовать интерфейс IExtensionApplication public void Initialize() < >public void Terminate() < >> > >
Код весьма незамысловат: имеется две процедуры — drawFigure(double x, double y) и drawBlock(double x, double y) . Первая отрисовывает в заданной точке набор фигур, в точности повторяющий наш блок, а вторая создает в заданной точке вхождение нашего блока.
Далее следуют две команды — HabrCommand_DrawFigures и HabrCommand_DrawBlocks. Первая отрисовывает на чертеже 10 000 наборов фигур, вторая — 10 000 вхождений блока.
Результаты работы



Десять тысяч наборов фигур:

Десять тысяч вхождений блока:
Запустим AutoCAD, выполним первую команду, сохраним чертеж. Затем закроем AutoCAD и повторим аналогичную процедуру для второй команды. В итоге получим два dwg-файла. Сравним их размеры.
Конец немного предсказуем:
Файл с наборами фигур:

Файл с вхождениями блока:
Первая причина
Некоторое увеличение размера файла чертежа — это нехорошо, но не так уж и страшно: Россия большая, места хватит всем. Однако есть проблемы и посерьезнее.
Представим, что в вышеупомянутый Приказ №1500 внесли дополнение, жестко регламентирующее расположение пуговицы на погоне, и нам нужно перенести на всех погонах окружность несколько выше от текущего положения.
Если мы использовали блоки, то задача решается в несколько строк кода: мы просто откроем определение блока, найдем там окружность и сдвинем ее центр в нужную точку. Поскольку все вхождения блока ссылаются на одно и то же определение, после выполнения команды все они обновятся автоматически.
Код команды:
[CommandMethod("HabrCommand_MoveButton")] public void HabrCommand_MoveButton() < // получаем ссылки на документ и его БД Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; // поле документа "Editor" понадобится нам для вывода сообщений в окно сообщений AutoCAD Editor ed = doc.Editor; // имя нашего блока const string blockName = "ltBlock"; // начинаем транзакцию Transaction tr = db.TransactionManager.StartTransaction(); using (tr) < // открываем таблицу блоков на запись BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); // проверяем, есть ли в таблице блок с таким именем // если нет - выводим сообщение и завершаем выполнение команды if (!bt.Has(blockName)) < ed.WriteMessage("Block not found!"); return; >else < // открываем определение блока на запись BlockTableRecord btr = tr.GetObject(bt[blockName], OpenMode.ForWrite) as BlockTableRecord; // перебираем по очереди ID всех графических объектов блока foreach (ObjectId id in btr) < // для каждого ID получаем сам объект, открываем его на чтение DBObject obj = tr.GetObject(id, OpenMode.ForRead); // если тип объекта - окружность (Circle), то открываем ее на запись и задаем ей новый центр if (obj.GetType() == typeof(Circle)) < obj.UpgradeOpen(); (obj as Circle).Center = new Point3d(0, 100, 0); >> // фиксируем транзакцию tr.Commit(); > >
Как читатель уже наверняка заметил, в этой команде происходит редактирование блока. Ничего запредельного в этом нет; в одной из следующих статей я постараюсь чуть подробнее осветить вопросы выбора элементов на чертеже и их редактирования. Данный пример основан на этом (англ.) и этом (англ.) источниках. По второй ссылке, кстати, можно найти целых пять разных способов убедиться в том, что объект является окружностью. Мы, разумеется, использовали самый неэффективный простой и понятный из них.
Маленькая деталь: AutoCAD действительно обновит все вхождения блоков, однако чтобы это увидеть, необходимо выполнить команду REGEN:

Результат:

Безусловно, подобную операцию можно провернуть и в случае геометрических фигур, а не вхождений блоков, однако тогда придется работать уже со всем чертежом и менять координаты центра окружности не один раз, а десять тысяч. Тестов я не проводил, но думаю, что эта процедура займет несколько больше времени, чем редактирование определения блока.
С другой стороны, каждая монета имеет аверс и реверс, а использование блоков накладывает свои ограничения.
Например, если потребуется заменить лейтенантский погон, расположенный в одиннадцатой строке и сорок втором столбце, на капитанский, то при использовании блоков никаким нормальным способом мы это сделать не сможем.
Придется либо создавать новый блок для капитана, либо дорисовывать звездочки вручную, либо прибегать к каким-нибудь дополнительным извращениям.
NэBpaЩeHuЯ — одна из причин, по которым мне НЕ нравится программировать. С некоторых пор я работаю конторским пенсионером, чему искренне рад.
Краткий вывод (куда ж без него-то): использование блоков может сэкономить массу сил и времени, но применять их надо обоснованно, при наличии необходимости.
На этом я, пожалуй, завершусь. В следующий раз расскажу про поиск и редактирование объектов на чертеже. Как всегда, буду рад любым отзывам, замечаниям и предложениям — в комментариях или ЛС.
AutoCAD. Настройка и создание собственной уникальной среды разработки
Для высокоскоростного проектирования всегда необходима солидная база элементов с различными параметрами и конфигурациями. Все эти элементы реализуются в AutoCAD в виде блоков.
Блок в AutoCAD – это объект или набор объектов, имеющий имя и воспринимающийся как один объект (все объекты, которые входят в состав блока сгруппированы в один цельный объект). Использование блоков на чертежах существенно уменьшает время вычерчивания и редактирования одинаковых элементов на чертеже, так как изменив определение блока, и автоматически редактируются и все его вхождения.
Блоки бывают двух видов: статические и динамические. Статические блоки в AutoCAD – это группа объектов, объединённых в цельный объект, представляющий из себя блок. Мало чем отличается от группы. Динамичность блока может заключаться в изменении его размеров, масштаба, угла поворота и даже структуры. Необходимость динамического блока состоит в том, что он служит для уменьшения общего количества элементов в библиотеках и файлах. Динамические блоки позволяют указать типы и количество вариаций для каждого блока.
Так как мы рассказываем о блоках, важно понимать, что есть вхождение, а что определение блока в AutoCAD. После того как начерчены элементы, преобразуем их в блок: выберем команду «Создать блок», зададим имя, базовую точку и укажем элементы. Определение блока – это информация об имени, базовой точке и объектах, входящих в состав блока. Вхождением же блока является вставленный в чертеж блок, представляющий из себя цельный объект и отображающий данные определения. За вхождение блока отвечает команда «Вставка».
Вот вам пример: создадим элемент, с помощью блока, вхождение которого на будущем чертеже повторится ещё много раз. Но после завершения чертежа возникла необходимость изменить все эти повторяющиеся элементы. Преимущество блоков заключается в том, что достаточно будет изменить лишь определение блока, а все вхождения автоматически изменятся аналогично. В ином случае пришлось бы редактировать каждый элемент отдельно или изменить один, удалить остальные и заново делать копии.
Важно понимать, что блоки – это просто графические ссылки в область данных файла, где лежит само описание блока. Именно поэтому использование блоков в Автокад существенно сокращает размер файла.
Начнём с того, что создадим статический блок. Нарисуем с помощью стандартных примитивов любой элемент.
Теперь создадим из него блок, который будет иметь базовую точку. Все объекты блока сгруппируются в одну именованную «группу». Для создания определения блока нужно:
Открыть вкладку «Вставка», в панели «Определение блока» есть кнопка «Создать блок», кликнуть по ней. Также в командной строке можно ввести псевдоним команды «БЛОК» — «б» и нажать кнопку «Enter».
В открывшемся окне надо:
Дать блоку уникальное имя. Если вы совершили опечатку в названии, то знайте, что блок можно всегда переименовать.
Задать базовую точку, в качестве которой рекомендуется указывать какую-нибудь характерную точку объекта.
Выбрать объекты, которые должны войти в блок. Также присутствует группа переключателей, определяющих, что делать с выделенным набором объектов после объединения в блок.
— Оставить
— Преобразовать в блок
— Удалить
Теперь нажмите кнопку «ОК». В результате исходные объекты преобразуются в блок и будут выглядеть следующим образом:
Теперь нужно вставить блок в чертеж. Для этого перейдём во вкладку «Вставка», в ней на панели «Блок» нажмём на кнопку «Вставить».
В появившемся окне укажем:
— Имя из списка определений. Миниатюра внешнего вида подскажет как выглядит выбранный блок.
— Точку вставки, масштабный коэффициент и угол поворота. Точку вставки лучше указывать на самом чертеже. Для этого установим опцию «Указать на экране». Для иных параметров можно ввести конкретные значения.
Теперь создадим динамический блок. Добавим динамические свойства сделанному блоку. Выберем наш блок, нажмём правую кнопку мыши и кликнем на пункт «Редактор блоков», после чего попадаем в новое окно – окно редактора блоков.
Редактор блоков выглядит следующим образом:
С помощью палитры вариаций блоков нам и предстоит добавлять «динамичности» блоку.
Для этого сначала добавим Параметр, который и будет изменяться, а затем укажем Операцию, т.е. укажем каким образом будет параметр меняться (растягиваться или масштабироваться).
Заходим во вкладку «параметры», выбираем «линейный» и отмечаем две точки, в нашем случае, это начало и конец объекта, вдоль которых и будет производиться растяжение. Затем отводим параметр вправо и ещё раз кликаем левой кнопкой мыши. После этого должен появиться желтый квадратик с восклицательным знаком, означающий, что мы добавили параметр.
Создадим операцию (скажем команде «Расстояние 1» как она будет меняться). В нашем случае это будет операция «Растяжение». Для этого во вкладке «Операции» выбираем пункт «Растянуть» и кликаем на синий параметр «Расстояние 1».
После этого следует указать, где будет располагаться ручка растягивания/сужения блока. Кликаем по нижнему краю круга. Там должен был появиться красный крест в красном кружочке.
Теперь нас попросят указать «первый угол рамки растягивания», а затем «противоположный угол», т.е. нам нужно пересечь рамкой все объекты, которые предназначены для растяжения, а объекты, которые должны будут просто перемещаться необходимо поместить полностью внутрь рамки.
Теперь выберем объекты, подвергающиеся операции “растягивание”. Выбираем все линии по очереди или выделяем их рамкой и подтверждаем наши все вышеперечисленные действия нажатием на клавишу «Enter». После всего выполненного, около нашего динамического блока должна была появиться пиктограмма растяжения, означающая, что операция успешно добавлена к параметру.
Сохраним изменения и выйдем из редактора. Кликнем на зелёную галочку и сохраняем изменения (обязательно!).
Выделяем наш блок.
В центре находится базовая точка, с помощью которой можно перемещать блок. Также на блоке расположен треугольник, потянув за который можно изменить размер самого окна (растянуть или сузить).
Вот такая жуть получилась, так как мы выделили полностью круг (он просто перемещается), просто пересекли линии (они растягиваются) и даже не коснулись стрелки (бездвижны) на Рисунке 14.
Рассмотри ещё одну возможность динамических блоков – задание дискретных свойств. Мы установим конкретные параметры изменения по длине. Для этого выделим блок и зайдём в редактор блоков.
Там выберем параметр «Расстояние 1» и кликнем по нему правой кнопкой мыши. Во всплывающем окне выберем пункт «Свойства».
Откроется окно «Свойства». В пункте «Набор значений», в подпункте «Типе расст» выберем тип «Список». Это нужно для того, чтобы у нас был список конкретных значений по размерам.
После этого кликаем на квадратик справа от пункта «Список значений расс…». Нам откроется новое окно, для задания нужных значений возможного изменения размеров блока.
Это окно выглядит так, как представлено на Рисунке 22. В нём нужно вписать значения и добавить их в общий список, после чего нажать на кнопку «ОК». Я добавлю значения 5, 25 и 100.
Можем закрыть «Редактор блоков» и сохранить сделанные изменения. Теперь у нас есть возможность растягивать блок только по установленным нами, только что, значениям, которые мы указали в списке. Это может пригодиться, когда потребуются типовые значения на чертежах.
На этом всё. Пробуйте и начните использовать различные операции и параметры для создания динамических блоков, чтобы быть лучшим проектировщиком!
