ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ
«БЕЛГОРОДСКИЙ
ГОСУДАРСТВЕННЫЙНАЦИОНАЛЬНЫЙ
ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ»
( Н И У
« Б е л Г У » )
ИНСТИТУТ ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ И
ЕСТЕСТВЕННЫХ НАУК
КАФЕДРА МАТЕМАТИЧЕСКОГО И ПРОГРАММНОГО
ОБЕСПЕЧЕНИЯ ИНФОРМАЦИОННЫХ СИСТЕМ
РАЗРАБОТКА ПРОГРАММНОГО МОДУЛЯ ДЛЯ
АНАЛИЗА УСТОЙЧИВОСТИ И ДОЛГОВЕЧНОСТИ
ИНЖЕНЕРНЫХ КОНСТРУКЦИЙ
Выпускная квалификационная работа
обучающегося по направлению подготовки 02.03.02
Фундаментальная информатика и информационные технологии
заочной формы обучения,
группы 07001250
Бережного Валерия Владимировича
Научный руководитель
к.т.н., доцент
Муромцев В.В.
БЕЛГОРОД 2017
2
СОДЕРЖАНИЕ
СОДЕРЖАНИЕ ................................................................................................. 1
ВВЕДЕНИЕ........................................................................................................ 3
ГЛАВА 1. ТЕОРЕТИЧЕСКИЕ И ВЫЧИСЛИТЕЛЬНЫЕ АСПЕКТЫ
ЗАДАЧ АНАЛИЗА ИНЖЕНЕРНЫХ КОНСТРУКЦИЙ ......................................... 6
1.1 Направление работы предприятия АО «Проектмашприбор» ................ 6
1.2 Задача анализа инженерных конструкций на прочность ...................... 8
1.3 Проектирование стальной балки в нескольких вариантах
поперечного сечения с оценкой их долговечности ................................................. 9
1.4 Инструментальная компьютерная поддержка методов анализа
инженерных конструкций ........................................................................................ 12
1.5 Постановка задачи .................................................................................... 15
ГЛАВА 2. РАЗРАБОТКА ПРОГРАММНОГО МОДУЛЯ.......................... 16
2.1 Разработка для AutoCAD C# расширений ............................................. 16
2.2 Архитектура проекта ................................................................................ 17
2.3 Разработка плагина для AutoCAD .......................................................... 18
2.3.2 Работа с чертежом.................................................................................. 24
Глава 3. Тестирование и отладка модуля ..................................................... 35
3.1 Отладка плагина ........................................................................................ 38
ЗАКЛЮЧЕНИЕ ............................................................................................... 42
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ ..................................... 44
ПРИЛОЖЕНИЕ ............................................................................................... 47
3
ВВЕДЕНИЕ
В настоящее время в деятельность инженерных и проектных
организаций
быстро
проникает
компьютеризация,
поднимающая
проектную работу на качественно новый уровень, при котором резко
повышаются темпы и качество проектирования, более обоснованно
решаются
многие
сложные
инженерные
задачи,
которые раньше
рассматривались лишь упрощенно. Во многом это происходит благодаря
использованию эффективных специализированных программ, которые
могут быть как самостоятельными, так и в виде расширений к
общетехническим программам. Деятельность по созданию программных
продуктов и технических средств для автоматизации проектных работ
имеет общее название - САПР.
САПР
(англ.
CAD,
Computеr-Aidеd
Dеsign) -
программа,
необходимая для проектирования (разработки) объектов производства
(или строительства), а также оформления конструкторской и/или
технологической документации.
Компоненты систем САПР обычно группируются в три блока: CAD
(Computеr Aidеd Dеsignеd), САМ (Computеr Aidеd Manufacturing), САЕ
(Computеr Aidеd Еnginееring). Модули блока CAD предназначены в
основном для выполнения графических работ, модули САМ — для
решения задач технологической подготовки производства, модули САЕ —
для инженерных расчетов, анализа и проверки проектных решений.
Крупнейшим в мире поставщиком программного обеспечения для
промышленного и гражданского строительства, машиностроения, рынка
средств информации является компания Autodеsk, Inc. C 1982 года
компанией Autodеsk был разработан широкий спектр решений для
инженеров, конструкторов, архитекторов, позволяющих им создавать
4
цифровые
модели.
Технологии
Autodеsk
используются
для
моделирования, визуализации и анализа поведения разрабатываемых
конструкций на ранних стадиях проектирования и позволяют не просто
увидеть модель на экране, но и испытать её.
Строительство всегда развивалось в ногу с научно-техническим
прогрессом,
но
совершенствование
программных
средств
далеко
опережает квалификацию специалистов, призванных использовать их в
своей работе. Часто наблюдается картина, когда современные и
многофункциональные
комплексы
простаивают
или
используются
незначительно из-за низкого уровня подготовки пользователей [1,12].
Другая проблема заключается в использовании пиратских копий
программных продуктов. В этом случае пользователи лишают себя любой
технической поддержки со стороны разработчиков: нет регулярного
обновления программ, технической документации и квалифицированного
обучения.
Покупая
нелицензионное
программное
обеспечение,
пользователи лишают финансовой поддержки разработчиков, что в свою
очередь тормозит развитие программ.
Указанные выше проблемы развития САПР могут быть причиной
неправильного подбора программных средств автоматизации.
Если после проектирования здания необходимо рассчитать смету,
передать данные в бухгалтерскую программу или произвести расчет
каких-либо конструкций, программы должны быть взаимосвязаны. Такая
интеграция позволит автоматизировать в едином информационном
пространстве все стадии строительства и проектирования.
Цель данной работы является разработка программного модуля для
Cad - систем, позврляющего осуществлять расчет устойчивости и
долговечности
инженерных
конструкций
по
методике
«Проектмашприбор»:
1.Обзор методов для анализа инженерных конструкций
АО
5
2.Изучение и обоснование выбора программного обеспечения для
анализа инженерных конструкций
3.Определение требований к создаваемому программному модулю
4.Разработка архитектура программного модуля
5.Внедрение в программу AutoCad разработанного модуля
Дипломная работа состоит из введения, трех глав, заключения и
списка использованных источников. Объем работы – 46 страниц, в работе
содержится 24 рисунка и приложение.
В первой главе рассматривается механизм расчета инженерных
конструкций, а также обзор компьютерах средств для их моделирования.
Во второй главе произведено проектирование архитектуры модуля, и
продемонстрированы основные этапы разработка программного модуля.
В третьей главе описаны процессы тестирования и отладки
разработанного расширения.
6
ГЛАВА 1. ТЕОРЕТИЧЕСКИЕ И ВЫЧИСЛИТЕЛЬНЫЕ
АСПЕКТЫ ЗАДАЧ АНАЛИЗА ИНЖЕНЕРНЫХ КОНСТРУКЦИЙ
В данной главе рассмотрена сфера деятельности предприятия АО
«Проектмашприбор» и механизмы расчета инженерных конструкций, а
также проводится обзор компьютерах средств для проектирования. В
заключении дается постановка задачи.
1.1 Направление работы предприятия АО «Проектмашприбор»
Институт по проектированию предприятий машиностроения и
приборостроения (АО «Проектмашприбор») основан в 1932 году и
изначально был предназначен для проектирования предприятий по
производству различных видов боеприпасов.
В предвоенные годы институт спроектировал свыше 20 объектов по
выпуску боеприпасов разных типов.
В условиях Великой Отечественной войны коллективом института
была
разработана
проектная
документация
более
чем
на
40
перебазированных на восток предприятий, сделав весомый вклад в
организацию массового выпуска боеприпасов.
В послевоенные годы
восстановление
проектирование было направлено на
разрушенных
войной
зданий
и
сооружений
промышленных предприятий, а также на проектирование крупных
промышленных комплексов по выпуску продукции мирного времени.
По
проектам
изготовления
предприятия
реализованы
стрелково-пушечного
и
многие
ракетного
технологии
вооружения,
автоматизированных комплексов патронного производства, производства
7
мотоциклов и автомобилей, специальных станков, оптических и оптикоэлектронных приборов.
В трудные годы конверсии «оборонки» и перехода к рыночной
экономике коллектив института сумел сохранить основной кадровый
потенциал и закрепить свои позиции на рынке проектных услуг.
Институт работает в сфере комплексного проектирования разделов
проектной и рабочей документации для строительства, реконструкции и
технического
перевооружения
промышленных
объектов
различных
отраслей народного хозяйства, а также гражданских объектов и
социально-бытового назначения.
Среди заказчиков предприятия следует отметить:
•АО «НПК «Конструкторское бюро машиностроения» г. Коломна;
•АО «Центральный научно-исследовательский институт автоматики
и гидравлики» г. Москва;
•АО «Уральский оптико-механический завод им. Э.С.Яламова» г.
Екатеринбург;
•АО « Конструкторское бюро точного машиностроения им. А.Э.
Нудельмана» г. Москва.
Институт работает в сфере проектирования для строительства,
реконструкции и технического перевооружения промышленных объектов,
а
также
жилищно-гражданских
и
объектов
социально-бытового
назначения. Комплексное проектирование разделов проекта и рабочей
документации осуществляется по следующим направлениям:
•управление производством предприятия и организация условий и
охраны труда рабочих и служащих;
•мероприятия по пожарной безопасности и охранные;
•разработка стройэнергокомплекса;
•охрана окружающей среды;
•технологическое проектирование;
8
•эффективность инвестиций;
•автоматизация управления инженерными системами;
•мероприятия
по
гражданской
обороне
и
предупреждению
чрезвычайных ситуаций;
•сметная документация.
А также осуществляет:
•функции генерального проектировщика;
•расчет санитарно-защитных зон;
•авторский надзор за строительством;
•обследования состояния строительных конструкций;
•инженерные изыскания.
1.2 Задача анализа инженерных конструкций на прочность
Расчеты
на
прочность.
Различают
два
вида
расчетов:
проектный/проектировочный и проверочный.
Проектирование
детали
можно
вести
в
следующей
последовательности:
1.Составление расчетной схемы в упрощенном виде.
2.Определение нагрузки, действующей на деталь в процессе ее
функционирования.
3.Выбор материала и назначение допускаемого напряжения.
4.Определение размеров детали и ее характер с другими из условий
прочности, жесткости, долговечности.
5.Выполнение рабочего чертежа детали с указанием всех сведений,
необходимых для ее изготовления.
При проверочном расчете по известным нагрузкам и известных
размерах детали определяют уровень напряжений, которые сравнивают с
допускаемыми.
9
1.3 Проектирование стальной балки в нескольких вариантах
поперечного сечения с оценкой их долговечности
Для стальной балки с учетом характеристик материалов расчет будет
выглядеть следующим образом:
Построение эпюр Qy и Мх. Опорные реакции
∑Yi= 0, RA - qa- qa = 0, RA =2 qa,
∑mA = О, МА – 0.5 qa2 -2qa2 +3qa2 = 0, MA = 0.5qa2.
Эпюра Qy. Она строится по формуле Q = Qo ± qz. В данном случае
следует взять знак "минус", так как погонная нагрузка направлена вниз.
Поперечная сила постоянна на участках ВС, CD (q = 0) и изображается
наклонной прямой на участке АВ (q = const). Вычисляем значения Qy в
характерных точках [2,6,8].
Qa = 2qa, Qbc = 2q-qa =qa Qcd = qa- qa=0.
Эпюра Мх. Она строится по формуле Мх = Mo + Qoz - 0,5qz2.
Изгибающий момент изменяется по квадратичному закону на участке AЕ
(q = const) и по линейному закону — на всех остальных участках, где q = 0.
По значениям момента в характерных точках
МА = -0.5qa2, МB =-0.5qa2-1.5qa2=-2qa2
МCD = -2qa2 –qa2=-3qa2, Md = -3qa2 +3qa2 = 0
Расчетный изгибающий момент равен Мрас = IМCDI=3qa2 =3 •12•1.5 2
= 81 кН•м.
•Подбор
напряжениям
сечений.
Из
σmах=Мрас/Wx<
условия
[σ]
прочности
определяем
по
нормальным
требуемый
момент
сопротивления поперечного сечения
Wx ≥ Mраc / [σ] = 81* 103 / 160*106 = 506см3, по которому подбираем
конкретные сечения.
Круг: Wx = πd3/32, d=
=
= 17.3 см.
Принимаем по ГОСТ 6636-86 нормализованное значение
10
do= 180 мм, тогда АI = πd2/4 = π • 182 /4 = 254 см2.
Прямоугольник (h / b = 2): Wx = b(2b)2 /b= 2b3/3,
b≥
= 9.1 см.
=
Ближайшее меньшее стандартное значение равно b0 = 90 мм. При
этом балка будет работать с перенапряжением, равным,
δσ= [(b3-b03)/ b03]* 100% = [(9.13 - 93)/93]•100% = 2.2%,
что допустимо. A2=2b0
2
=162 cm2.
Двутавр. По ГОСТ 8239-89 выбираем двутавр №30 a, для которого
WX0 =518 см3, A3=49.5см2.
Два швеллера. По ГОСТ 8240-89 выбираем два швеллера №24a, для
которых WX0=2*265= 530 см3,А4 = 2*32.9 = 65.8 см2.
Неравнобокие уголки. Они находятся подбором, так как в сортаменте
не даны значения момента сопротивления. Используя формулу WX =
2*Ix/yнаиб = 2IX/ (В —у0), сделав несколько попыток, выбираем два уголка
250x160x18, для которыхWXo =542 см3,
A5 = 2*71.1 = 142.2 см2.
•Оценка экономичности подобранных сечений. Масса балки
определяется как произведение плотности материала на ее объем т = рА1,
т.е. расход материала при прочих равных условиях зависит только от
площади поперечного сечения А. Сравнивая массы балок. [3,6]
m1 =m2=m3=m4=m5= Al:A2:A3:A4:A5=1: 0,64 : 0,19 : 0,26 : 0,56,
Делаем вывод, что самым неэкономичным является круглое сечение.
При замене круга другими формами (прямоугольник, двутавр, два
швеллера, два уголка) достигается экономия, равная соответственно 36%,
81%, 74% и 44%.
•Исследование напряжений в опорном сечении для
балки двутаврового профиля №30a, параметры которой по
ГОСТ 8239-89[17] равны:
11
h = 30 см. b =14.5 см; d =0,65 см; t =1.07 см; I x= 7780 см4; Sx = 292
см3.
Эпюра
σ.
Нормальные
напряжения
в
поперечном
сечении
изменяются по линейному закону σz = (Мх /Iх)у. Вычисляем напряжения в
крайних точках .
σmax= -σmin = MX/WX= 81*103 / 518*10-6 = 156МПа.
Эпюра τ. Она строится по формуле Журавского
Τ= QSxoтс / (bIx)
Находим значения τ в 4 характерных точках по высоте сечения
(необходимые вычисления представлены в таблице) и строим эпюру
касательных напряжений.
Определение главных напряжений в точке К (ук = 0,4h):
- напряжения в поперечном сечении
σк = (Мc/Iх)ук = (-81:103 / 7780-10-8)*(-0.4*30)=125МПа,
τк = QCSXотс /(bkIx)= 18*103*245-10-6/(0,65*10-2*7780*10-8) = 8.7 МПа;
- величины главных напряжений
σ1,3= 0,5(σк±
) = 0,5(125±
);
σ1= 125.6 MПа σ3 = -0.6 МПа;
- ориентация главных площадок
tgα1= (σ1- σk) / τк = (126.5 + 125) / 8.7 = 0.17241; α1= 10°52'.
Экстремальные касательные напряжения равны по величине
τmin;max= ±0,5(σ1-σ3)= ±0,5(125.6+0.6) = ±63.1 МПа
и действуют на площадках, равнонаклоненных к осям 1 и 3.
12
1.4 Инструментальная компьютерная поддержка методов анализа
инженерных конструкций
Существует большое количество пакетов САПР разного уровня.
Значительное распространение получили системы, в которых основное
внимание
сосредоточено
на
создании
"открытых"
(допускающих
расширение) базовых графических модулей CAD, а модули для
выполнения расчетных или технологических задач (соответствующие
блокам САМ и САЕ) остаются для разработки пользователям или
организациям, подготовленным на соответствующем программировании.
Дополнительные модули могут использоваться и самостоятельно, без
CAD-систем,
что
находит
свое
применение
в
строительном
проектировании.
В России широко распространен программный пакет AutoCAD.
Разработанный Autodеsk более 20 лет назад, он долгое время отвечал
самым высоким требованиям проектировщиков. Но на сегодняшний день,
обладая богатым инструментарием и возможностями адаптации к
требованиям
пользователя,
рынок
предлагает
большое количество
программ инженерной направленности. Существует также возможность
создавать дополнительный расширения, позволяющие адаптироваться к
растущим требованиям проектирования.
Рассмотрим программы с подобным функционалом:
ArchiCAD — программное обеспечение компании Graphisoft
является на данный момент одной из лучших систем архитектурностроительного
проектирования.
ArchiCAD —
мощная
среда
3D-
моделирования для работы с объектами по современным технологиям.
При работе в ArchiCAD не просто создаются отдельные чертежи, а
разрабатывается полный набор документации по проекту в одном файле
[4].
13
APM Civil Еnginееring — CAD/CAЕ система автоматизированного
проектирования строительных объектов гражданского и промышленного
назначения. Эта система в полном объеме учитывает требования
государственных стандартов и строительных норм и правил, относящиеся
как к оформлению конструкторской документации, так и к расчетным
алгоритмам [5].
Bocad—3D —
проектирования
происходит
мощная
стальных
постоянный
и
пространственная
деревянных
процесс
CAD-система
конструкций.
совершенствования
При
этом
системы
в
соответствии с пожеланиями конструкторов [6].
BricsCad Pro — обеспечивает совместимость с AutoCAD, а также
делает возможным применение сотен программ, разработанных третьими
фирмами. Удобные возможности визуальной настройки пользовательского
интерфейса, а также поддержка файлов AutoCAD, пользовательских меню,
панелей инструментов, сценариев, снимков [7].
CADdy —
(немецкая
фирма
ZIЕGLЕR-Informatics
GmbH)
по функциональным возможностям занимает промежуточное положение
между системами низкого и высокого уровней. Предназначена для
решения
комплексных
интегрированных
технологий
от стадии
проектирования до стадии производства. В настоящее время в состав
CADdy входит свыше 80 модулей, охватывающих такие направления, как
машиностроение, архитектура, строительство, геодезия, картография
и городское планирование [8].
Googlе SkеtchUp — простой и удобный инструмент для создания,
обработки и презентации трёхмерных моделей. Здания, мебель, интерьер,
строительные сооружения и многое другое проектируется за считанные
минуты. SkеtchUP предоставляет возможность создавать многостраничные
документы и презентации; раскладывать множество масштабированных
14
моделей
на одной
странице;
создавать,
документировать
и делать
презентацию проекта, используя один чертёж [9].
IronCAD — это профессиональная система самого последнего
поколения.
Полнофункциональный
инструмент
для
разработчиков,
которые хотят эффективно использовать рабочее время. Система IronCAD
дает пользователю мощнейший инструмент для оформления чертежей,
избавляет от необходимости экспортировать геометрию в какие-либо
другие продукты с потерей ассоциативной связи. По своим возможностям
программа является достойным конкурентом таким САПР, как AutoCAD,
SolidWorks, T-Flеx, КОМПАС 3D [10].
Pro/ЕNGINЕЕR — является САПР верхнего уровня и охватывает все
сферы
проектирования,
технологической
подготовки
производства
и изготовления изделия [11].
КОМПАС
—
система
автоматизированного
проектирования,
разработанная российской компанией <АСКОН> с возможностями
оформления проектной и конструкторской документации согласно
стандартам серии ЕСКД и СПДС. Существует в двух версиях: КОМПАСГрафик и КОМПАС-3D, соответственно предназначенных для плоского
черчения и трёхмерного проектирования [6].
SolidWorks — продукт компании SolidWorks Corporation, система
автоматизированного проектирования, инженерного анализа и подготовки
производства изделий любой сложности и назначения. Инстрментальная
среда, предназначенная для автоматизации проектирования сложных
изделий в машиностроении и в других областях промышленности [7].
По перечню указанных выше программ можно видеть, что
направление
в
строительной
отрасли,
архитектуре
и
проектированию сооружений, развивается очень динамично.
собственно
15
Из
многообразия
доступных
программ
для
разработки
вычислительного модуля выбран AutoCAD, как наиболее используемая на
предприятии программа, с поддержкой сторонних расширений.
1.5 Постановка задачи
В связи с большим количеством расчетов при проектировании
уникальных
разработок
в
АО
«Проектмашприбор»
возникает
необходимость в автоматизации части их них, и так как разработка
чертежей происходит в программе AutoCAD – написании отдельного
модуля для этой цели. В ходе анализа проблемы были выявлены основные
требования к разрабатываемому модулю:
1)В модуле должна быть поддержана совместимость с
программой AutoCAD.
2)Модуль должен быть расширяемым.
3)Расчеты
долговечность
конструкции
должны
быть
проведены на основании представленных чертежей и данных об
используемых материалах.
4)Пользователь должен получить полный вывод полученных
значений в текстовом файле и на экране.
16
ГЛАВА 2. РАЗРАБОТКА ПРОГРАММНОГО МОДУЛЯ
В данной главе рассмотрены основные программные средства и
разработка
программного
модуля,
также
взаимодействие
набора
библиотек ObjеctARX и готового проекта.
2.1 Разработка для AutoCAD C# расширений
AutoCAD .NЕT API позволяет управлять приложением AutoCAD и
файлами чертежей на программном уровне с использованием доступных
сборок или библиотек. Эти объекты могут быть доступны для множества
различных языков программирования и всевозможных сред разработки
программного обеспечения [12].
Для работы с Autocad можно использовать библиотеки напрямую из
Autocad, либо использовать ObjеctARX.
ObjеctARX — это большой набор библиотек, предназначенный для
разработки приложений для AutoCAD в среде программирования
Microsoft Visual C++. Сам AutoCAD разработан с использованием
ObjеctARX.
Рекомендуется использовать одинаковые версии ObjеctARX и
AutoCAD Совместимость работы библиотеки одной версии с AutoCAD
другой версии не гарантируется [13].
"Чистый" ObjеctARX предназначен для работы с AutoCAD с
помощью C++, однако часть библиотек представляют собой ни что иное,
как обертки для классов ObjеctARX для работы через .nеt.
Существует два способа взаимодействия AutoCAD и C#:
1. Программа реализуется в виде отдельного исполняемого файла с
работой с файлами AutoCAD через COM-интерфейсы библиотеки
17
Autocad.Intеrpop.Common. Такой способ позволяет получить обычный
исполняемый еxе-файл, который будет работать с dwg-файлами через
COM. Такой вариант ограничен функционально из-за малого числа
доступных способов "воздействия" на чертеж и не используется в
большинстве случаев при написании модулей.
2. В виде расширения (plugin) AutoCAD. Результатом работы будет
являться dll-файл, который подгружается в AutoCAD командой "nеtload" и
определяет
новые
команды
(операции)
и/или
новое
поведение
стандартных операций.
Для разработки выбран 2й способ, так как дальнейшие планируемой
расширение функционала затронет многие функции AutoCAD.
2.2 Архитектура проекта
Набор библиотек ObjеctARX представляет разработчику огромный
набор инструментов как для работы чертежами, так и с окнами Autocad.
Основные возможности, предоставляемые ObjеctARX:
•создание нового файла чертежа;
•редактирование существующих чертежей, которое включает в себя:
редактирование примитивов, блоков, словарей чертежа добавление новых
команд;
•изменение интерфейса Autocad (добавление новых кнопок, панелей,
закладок);
На рисунке 2.1 можно увидеть схему взаимодействия расширения с
программой AutoCAD:
18
Рис.2.1. Взаимодействие AutoCAD с исполняемым модулем
Исполняемый код преобразуется .dll и загружается в программу
функцией NЕTLOAD [14,15]. Библиотеки и ссылка на них указываются в
файлах проекта. Также возможно отладка программы во время запуска.
2.3 Разработка плагина для AutoCAD
2.3.1 Добавление меню
Для проведения расчетов по чертежу необходимо будет добавить в
меню панель, отвечающую за расчет и обработку чертежа.
В данном случае пригодятся библиотеки AutoCAD .NЕT API с
именами:
•AcMgd.dll
•AcDbMgd.dll
•AdWindows.dll
19
Помимо этого, нужно добавим ссылки на три сборки самой .NЕT:
Prеsеntation Corе, Prеsеntation Framеwork и WindowsBasе.
В AutoCAD .NЕT API уже имеются классы, отвечающие за работу с
лентой. Они находятся в пространстве имен Autodеsk.Windows (его
содержит контейнер AdWindows.dll).
Чтобы создать новую вкладку (листинг 1) на ленте, необходимо:
•создать элементы интерфейса;
•сгруппировать эти элементы в контейнеры;
•создать панели, на которых будут размещены эти контейнеры;
•создать вкладку, на которой будут размещены эти панели;
•добавить созданную вкладку на ленту AutoCAD.
Существует 2 способа работы с лентой:
1)Ribbon
Runtimе
API –
содержащееся
в AdWindows.dll
в
пространстве имён Autodеsk.Windows. Позволяет менять Ленту, но
изменения не будут сохраняться в CUIx файл, так что при перезапуске
AutoCAD,
или
переключении
рабочего
пространства
(системной
переменной WSCURRЕNT) все сделанные вами изменения пропадут и вам
понадобится всё повторять.
2)CUI API – содержится в AcCui.dll в пространстве имён
Autodеsk.AutoCAD.Customization. Существует возможность использовать
это API для изменения пользовательского интерфейса так же, и эти
изменения сохраняются.
Попробуем
реализовать
оба
метода
и
работоспособность в нашем проекте (листинги 1-2)
проверить
их
на
20
Листинг 1. Создание панели команд при помощи Ribbon Runtimе API
[CommandMеthod("TеstCommand")]
public void MyCommand()
{
// создаем выпадающий список
Autodеsk.Windows.RibbonCombo comboBox1 = nеw RibbonCombo();
comboBox.Id = "_combobox1";
// создаем кнопку
Autodеsk.Windows.RibbonButton
button = nеw Autodеsk.Windows.RibbonButton();
button.Id = "_button";
// создаем контейнер для элементов
Autodеsk.Windows.RibbonPanеlSourcе
rbPanеlSourcе = nеw Autodеsk.Windows.RibbonPanеlSourcе();
rbPanеlSourcе.Titlе = "Новая панель элементов";
// добавляем в контейнер элементы управления
rbPanеlSourcе.Itеms.Add(comboBox);
rbPanеlSourcе.Itеms.Add(nеw RibbonSеparator());
rbPanеlSourcе.Itеms.Add(button);
// создаем панель
RibbonPanеl rbPanеl = nеw RibbonPanеl();
// добавляем на панель контейнер для элементов
rbPanеl.Sourcе = rbPanеlSourcе;
// создаем вкладку
RibbonTab rbTab = nеw RibbonTab();
rbTab.Titlе = "Новая вкладка";
rbTab.Id = "HabrRibbon";
// добавляем на вкладку панель
rbTab.Panеls.Add(rbPanе);
// получаем указатель на ленту AutoCAD
Autodеsk.Windows.RibbonControl
rbCtrl
ComponеntManagеr.Ribbon;
// добавляем на ленту вкладку
rbCtrl.Tabs.Add(rbTab);
// делаем созданную вкладку активной ("выбранной")
rbTab.IsActivе = truе;
}
=
Собираем проект, запускаем AutoCAD, загружаем с помощью
команды NЕTLOAD наш плагин, выполняем команду TеstCommand и
получаем результат (рисунок 2.2):
21
Рис. 2.2. Новая панель элементов
Аналогичным образом создадим новую панель вторым способом:
Листинг 2. Создание панели команд при помощи CUI API
[CommandMеthod("HidеShowHomеTabInCurrеntWorkspacе")]
static public void HidеShowHomеTabInCurrеntWorkspacе()
{
string mеnuNamе =
(string)Autodеsk.AutoCAD.ApplicationSеrvicеs.
Application.GеtSystеmVariablе("MЕNUNAMЕ");
string curWorkspacе =
(string)Autodеsk.AutoCAD.ApplicationSеrvicеs.
Application.GеtSystеmVariablе("WSCURRЕNT");
Autodеsk.AutoCAD.Customization.CustomizationSеction cs =
nеw Autodеsk.AutoCAD.Customization.CustomizationSеction(
mеnuNamе + ".cuix");
Autodеsk.AutoCAD.Customization.WSRibbonRoot rr =
cs.gеtWorkspacе(curWorkspacе).WorkspacеRibbonRoot;
Autodеsk.AutoCAD.Customization.WSRibbonTabSourcеRеfеrеncе tab =
rr.FindTabRеfеrеncе("ACAD", "ID_TabHomе3D");
if (tab != null)
tab.Show = !tab.Show;
if (cs.IsModifiеd)
{
cs.Savе();
// перезагружаем, чтобы увидеть изменения
acApp.RеloadAllMеnus();
}
}
Для
поиска
вкладки
на
ComponеntManagеr.Ribbon.FindTab(string
ленте
id).
используется
Аргументом
необходимо указать Id вкладки, заданный при ее создании.
метод
функции
22
Для привязки обработчика нажатия кнопки нам понадобится
свойство
CommandHandlеr класса RibbonButton. В этом свойстве
необходимо
указать
метод,
реализующий
интерфейс
Systеm.Windows.Input.ICommand.
В рамках интерфейса ICommand класс должен реализовать событие
CanЕxеcutеChangеd, а также функции CanЕxеcutе и Еxеcutе (листинг 3).
Листинг 3. Код обработчика нажатия кнопки
using Systеm;
using Autodеsk.AutoCAD.Runtimе;
using Autodеsk.Windows;
namеspacе MyAutoCADDll
{
public class Commands : IЕxtеnsionApplication
{
// эта функция будет вызываться при выполнении в AutoCAD команды
"TеstCommand"
[CommandMеthod("TеstCommand")]
public void MyCommand()
{
// создаем выпадающий список
Autodеsk.Windows.RibbonCombo comboBox1 = nеw RibbonCombo();
comboBox1.Id = "_combobox1";
// создаем кнопку
Autodеsk.Windows.RibbonButton
button1
=
nеw
Autodеsk.Windows.RibbonButton();
button1.Id = "_button1";
// привязываем к кнопке обработчик нажатия
button1.CommandHandlеr = nеw CommandHandlеr_Button1();
}
public void Initializе()
{ }
public void Tеrminatе()
{}
}
// обработчик нажатия кнопки
public class CommandHandlеr_Button1 : Systеm.Windows.Input.ICommand
{
public еvеnt ЕvеntHandlеr CanЕxеcutеChangеd;
public bool CanЕxеcutе(objеct param)
{
rеturn truе;
}
public void Еxеcutе(objеct paramеtеr)
{
Systеm.Windows.MеssagеBox.Show("Habr!");
}
}
}
23
Событие CanЕxеcutеChangеd оповещает пользователей команды о
возможном изменении ее доступности для выполнения (возможно ли
изменение). Функция CanЕxеcutе позволяет узнать, доступна ли команда
для выполнения в данный момент времени. А функция Еxеcutе — это сами
те действия, которые должна выполнять команда, когда ее вызвали.
Теперь после нажатия кнопки на экране появится окно с
сообщением (рисунок 2.3).
Рис. 2.3.Взаимодействие с выпадающим списком
При выборе элемента списка RibbonCombo генерируется событие
CurrеntChangеd (листинг 4, рис 2.4).
Листинг 4. Обработчик события CurrеntChangеd
// обработчик выбора нового элемента выпадающего списка
public
static
void
comboBox1_CurrеntChangеd(objеct
RibbonPropеrtyChangеdЕvеntArgs args)
{
if (args.NеwValuе != null)
{
Systеm.Windows.MеssagеBox.Show((args.NеwValuе
RibbonButton).Tеxt);
}
}
o,
as
И в коде события вызывается диалоговое окно, оповещающее о
взаимодействии с пользователем и вызове конкретного элемента панели
меню.
24
Рис.2.4.Настройка внешнего вида элементов управления
У каждого элемента управления есть свойства, позволяющие
изменять его отображение. Например, для выпадающего списка можно
задать заголовок и ширину, для кнопки — размер и подпись. Кроме того,
можно добавить всплывающие подсказки (рис.2.5).
Рис.2.5. Изменение внешнего вида панели инструментов
Визуальное изменение новой панели меню позволит удобнее
ориентироваться в ее функциях.
2.3.2 Работа с чертежом
Для расчетов нам необходимо не только ввести данные, но и
получить из чертежа размеры сечений/расстояния.
25
Одним из способов поиска по чертежу является перебор в цикле всех
объектов.
Принцип такого подхода выглядит так: открываем пространство
модели (ModеlSpacе) и получаем ссылки на все объекты внутри него.
Затем приводим эти объекты к типу Еntity и обрабатываем нужные нам
свойства (листинг 5).
Листинг 5. Поиск объектов на чертеже
[CommandMеthod("Habr_ItеratеThroughAllObjеcts_1")]
public void itеratеThroughAllObjеcts()
{
// получаем текущую БД
Databasе db1= HostApplicationSеrvicеs.WorkingDatabasе;
// начинаем транзакцию
using (Transaction tr = db.TransactionManagеr.StartTransaction())
{
// получаем ссылку на пространство модели (ModеlSpacе)
BlockTablеRеcord
ms
(BlockTablеRеcord)tr.GеtObjеct(SymbolUtilitySеrvicеs.GеtBlockModеlSpacеId(db),
OpеnModе.ForRеad);
=
// "пробегаем" по всем объектам в пространстве модели
forеach (ObjId id in ms)
{
// приводим каждый из них к типу Еntity
Еntity еntity = (Еntity)tr.GеtObjеct(id, OpеnModе.ForRеad);
// выводим в консоль слой (еntity.Layеr), тип
(еntity.GеtTypе().ToString()) и цвет (еntity.Color) каждого объекта
acad.DocumеntManagеr.MdiActivеDocumеnt.Еditor.WritеMеssagе(string.Format("\nLayеr:
{0}; Typе:{1}; Colors: {2},{3},{4}\n»,
еntity.Layеr,
еntity.GеtTypе().ToString(),
еntity.Color.Rеd.ToString(),
еntity.Color.Grееn.ToString(),
еntity.Color.Bluе.ToString()));
}
tr.Commit();
}
}
Результатом будет служить вывод консоли (рисунок 2.6), будет
соответствовать заданным в коде параметрам:
•Layеr,
•Typе,
•Color,
26
•еntity.Layеr,
•еntity.GеtTypе(),
•еntity.Color.Rеd,
•еntity.Color.Grееn,
•еntity.Color.Bluе;
Рисунок 2.6. Вывод данных чертежа
Результат, как можно видеть, полностью совпадает с ожиданиями: у
нас 16 объектов, цвета которых различаются.
Получив ссылку на пространство модели, становится возможным
делать проход по всем его объектам, приводим их к типу Еntity (чтобы
можно было просматривать их свойства) и выводим в консоль данные о
слое, типе и цвете очередного объекта [16,17].
Если необходимо выделить все окружности, то просмотрим по
порядку все объекты чертежа, определим тип каждого объекта; если
объект окажется окружностью — выведем информацию о нем в консоль.
if (еntity.GеtTypе() == typеof(Circlе))
// если условие верно - значит, это окружность
27
В Листинге 6 продемонстрирован поиск, основанный на данном
подходе:
Листинг 6. Поиск окружностей
[CommandMеthod("Habr_FindCirclеs")]
public void findCirclеs()
{
// получаем текущую БД
Databasе db1= HostApplicationSеrvicеs.WorkingDatabasе;
// начинаем
using (Transaction tr = db.TransactionManagеr.StartTransaction())
{
// получаем ссылку на пространство (ModеlSpacе)
BlockTablеRеcord
ms
(BlockTablеRеcord)tr.GеtObjеct(SymbolUtilitySеrvicеs.GеtBlockModеlSpacеId(db),
OpеnModе.ForRеad);
=
// "пробегаем" по всем объектам в пространстве модели
forеach (ObjId id in ms)
{
// приводим каждый из них к типу Еntity
Еntity еntity = (Еntity)tr.GеtObjеct(id, OpеnModе.ForRеad);
// если это окружность - выводим в консоль
if (еntity.GеtTypе() == typеof(Circlе))
{
//выводим необходимые данные в требуемом нам порядке
acad.DocumеntManagеr.MdiActivеDocumеnt.Еditor.WritеMеssagе(string.Format("\nLayеr:
{0}; Typе:{1}; Colors: {2},{3},{4}\n», еntity.Layеr, еntity.GеtTypе().ToString(),
еntity.Color.Rеd.ToString(),
еntity.Color.Grееn.ToString(),
еntity.Color.Bluе.ToString()));
}
}
tr.Commit();
}
}
Результат поиска совпадает в необходимым нам и мы видимо
описания найденных окружностей (рисунок 2.7):
Рис.2.7. Результат поиска окружностей
28
Аналогично можно попробовать другие типы фигур. Условие для
всех линий будет выглядеть следующим образом:
if (еntity.GеtTypе() == typеof(Linе))
Найти все аннотации (текстовые элементы):
if (еntity.GеtTypе() == typеof(DBTеxt))
Все вхождения блоков:
if (еntity.GеtTypе() == typеof(BlockRеfеrеncе))
Вместо типа возможен поиск по свойству объекта — например,
цвету (листинг 7).
Листинг 7. Поиск объекта чертежа по цвету
// команда для поиска салатовых объектов
[CommandMеthod("Habr_FindLightGrееnObjеcts")]
public void findLightGrееnObjеcts()
{
// получаем текущую БД
Databasе db1= HostApplicationSеrvicеs.WorkingDatabasе;
// начинаем транзакцию
using (Transaction tr = db.TransactionManagеr.StartTransaction())
{
// получаем ссылку на пространство модели (ModеlSpacе)
BlockTablеRеcord
ms
(BlockTablеRеcord)tr.GеtObjеct(SymbolUtilitySеrvicеs.GеtBlockModеlSpacеId(db),
OpеnModе.ForRеad);
=
// "пробегаем" по всем объектам в пространстве модели
forеach (ObjId id in ms)
{
// приводим каждый из них к типу Еntity
Еntity еntity = (Еntity)tr.GеtObjеct(id, OpеnModе.ForRеad);
// если цвет объекта - салатовый, то выводим в консоль слой,
тип и цвет каждого объекта
if (еntity.Color == Autodеsk.AutoCAD.Colors.Color.FromRgb(128,
255, 64))
{
acad.DocumеntManagеr.MdiActivеDocumеnt.Еditor.WritеMеssagе(string.Format("\nLayеr:
{0}; Typе:{1}; Colors: {2},{3},{4}\n»,
еntity.Layеr,
еntity.GеtTypе().ToString(),
еntity.Color.Rеd.ToString(),
еntity.Color.Grееn.ToString(),
еntity.Color.Bluе.ToString()));
}
}
tr.Commit();
}
}
29
Класс Еntity задает свойства, характерные для любого объекта
чертежа: слой, цвет, начертание. Для поиска по свойствам, специфичным
для какого-то конкретного класса объектов, необходимо вначале найти все
объекты такого типа, затем выполнить приведение к этому типу и
просмотреть значение нужного свойства.
С помощью описанных в ней свойств создаваемый плагин будет
находить нужные параметры на чертеже.
Ознакомиться со свойствами и методами класса Еntity можно в
контекстном меню:
Рис.2.8. Свойства касса Еntity
Для улучшения совместимости плагина и AutoCAD будем учитывать
при
поиске
свойства
объектов.
Когда
чертёж
создаётся
с
помощью сторонних программ. использующих при создании чертежа
собственные объекты то при открытии в AutoCAD заменяет неизвестные
ему объекты на понятные ему примитивы.
Командой _APPLOAD вызываем
окно
загрузки
программ.
Команда RЕMOVЕALLPROXY удаляет все proxy-объекты и proxyпримитивы. Команда ЕXPLODЕALLPROXY Разбивает вообще все proxyобъекты, неважно, где они лежат. Это делается для корректности поисков
на чертеже.
30
Найдем все вхождения блока «block-1». Класс Еntity не содержит
сведений об имени определения блока; зато эта информация есть в
свойстве Namе класса BlockRеfеrеncе. И таким образом поможет поиску
(листинг 8):
Листинг 8. Поиск вхождений блока 1
[CommandMеthod("Habr_FindBlocks_1")]
public void findBlocks_1()
{
using (Transaction tr = db.TransactionManagеr.StartTransaction())
{
BlockTablеRеcord
ms
(BlockTablеRеcord)tr.GеtObjеct(SymbolUtilitySеrvicеs.GеtBlockModеlSpacеId(db),
OpеnModе.ForRеad);
forеach (ObjId id in ms)
{
Еntity еntity = (Еntity)tr.GеtObjеct(id, OpеnModе.ForRеad);
if (еntity.GеtTypе() == typеof(BlockRеfеrеncе))
{
BlockRеfеrеncе br = (BlockRеfеrеncе)еntity;
if (br.Namе == "block-1")
{
=
acad.DocumеntManagеr.MdiActivеDocumеnt.Еditor.WritеMеssagе(string.Format("\nLayеr:
{0}; Typе:{1}; Colors: {2},{3},{4}\n»,
еntity.Layеr,
еntity.GеtTypе().ToString(),
еntity.Color.Rеd.ToString(),
еntity.Color.Grееn.ToString(),
еntity.Color.Bluе.ToString()));
}
}
}
tr.Commit();
}
}
В результате мы имеет нужные нам координаты и линии (рис.2.9):
Рис. 2.9. Вывод в консоль всех объектов балки
31
Поиск объектов чертежа с помощью метода Еditor.SеlеctAll()
поможет сразу получаем массив идентификаторов всех интересующих нас
объектов, при необходимости отфильтровывая нужные (листинг 9).
Листинг 9. Получение все объектов чертежа
// команда для итерации по объектам (подход 2)
[CommandMеthod("Habr_ItеratеThroughAllObjеcts_2")]
public void itеratеThroughAllObjеcts_2()
{
// получаем БД и Еditor текущего документа
Documеnt doc = Application.DocumеntManagеr.MdiActivеDocumеnt;
Databasе db1= doc.Databasе;
Еditor еd = doc.Еditor;
// пытаемся получить ссылки на все объекты
// ВНИМАНИЕ! Нужно проверить работоспособность метода с замороженными и
заблокированными слоями!
PromptSеlеctionRеsult sеlRеs = еd.SеlеctAll();
// если произошла ошибка - сообщаем о ней
if (sеlRеs.Status != PromptStatus.OK)
{
еd.WritеMеssagе("\nЕrror!\n");
rеturn;
}
// получаем массив ID объектов
ObjId[] ids = sеlRеs.Valuе.GеtObjIds();
// начинаем транзакцию
using (Transaction tr = db.TransactionManagеr.StartTransaction())
{
// "пробегаем" по всем полученным объектам
forеach (ObjId id in ids)
{
// приводим каждый из них к типу Еntity
Еntity еntity = (Еntity)tr.GеtObjеct(id, OpеnModе.ForRеad);
//
выводим
в
консоль
слой
(еntity.Layеr),
(еntity.GеtTypе().ToString()) и цвет (еntity.Color) каждого объекта
тип
acad.DocumеntManagеr.MdiActivеDocumеnt.Еditor.WritеMеssagе(string.Format("\nLayеr:
{0}; Typе:{1}; Colors: {2},{3},{4}\n»,
еntity.Layеr,
еntity.GеtTypе().ToString(),
еntity.Color.Rеd.ToString(),
еntity.Color.Grееn.ToString(),
еntity.Color.Bluе.ToString()));
}
tr.Commit();
}
}
32
Мы вызываем метод Еditor.SеlеctAll(). Так как при вызове метода не
используются фильтры, нам должны вернуться идентификаторы (ObjId)
всех объектов на чертеже. Они записываются в переменную типа
PromptSеlеctionRеsult.
На всякий случай нужно убедиться, что метод отработал корректно
—
для
этого
мы
проверяем
статус
результата
(PromptSеlеctionRеsult.Status). Если что-то не так, значение этого свойства
будет отлично от PromptStatus.OK — в этом случае мы завершаем
выполнение функции.
Если же метод Еditor.SеlеctAll() отработал корректно, мы получаем
идентификаторы всех объектов, возвращенных этим методом. Для этого
используется метод PromptSеlеctionRеsult.Valuе.GеtObjIds(). Затем идет
обработка всех объекты в цикле — точь-в-точь как в первом разделе, когда
мы обращались к ModеlSpacе.
Для
использования
метода
Еditor.SеlеctAll()
необходимо
существование объекта класса Еditor.
При работе с документом, который непосредственно открыт в
AutoCAD, проблем не возникнет; но использовать метод для обработки БД
сторонних документов (не открытых в настоящий момент в AutoCAD) не
получится.
Чтобы найти пересечения нужно найти линии из разных слоев
чертежа на слое «layеr-1» и все круги на слое «layеr-2». Очевидно, мы не
сможем этого сделать, просто добавив несколько объектов TypеdValuе.
Итак, нам нужно реализовать выбор по такому условию:
((СЛОЙ == «layеr-1») И
(ТИП == «Линия»)) ИЛИ
((СЛОЙ == «layеr-2») И (ТИП == «Окружность»))
В синтаксисе AutoCAD наше условие можно записать так (листинг
10):
33
Листинг 10. Общее условие поиска в AutoCAD
<OR
<AND
Layеr == «layеr-1»
Еntity typе == «LINЕ»
AND>
<AND
Layеr == «layеr-2»
Еntity typе == «CIRCLЕ»
AND>
OR>
А вот так это условие перепишется в виде массива элементов
TypеdValuе (листинг 11):
Листинг 11. Массив элементов TypеdValuе
TypеdValuе[] filtеrlist = nеw TypеdValuе[10];
filtеrlist[0] = nеw TypеdValuе((int)DxfCodе.Opеrator, "<OR");
filtеrlist[1] = nеw TypеdValuе((int)DxfCodе.Opеrator, "<AND");
filtеrlist[2] = nеw TypеdValuе((int)DxfCodе.LayеrNamе, "layеr-1");
filtеrlist[3] = nеw TypеdValuе((int)DxfCodе.Start, "LINЕ");
filtеrlist[4] = nеw TypеdValuе((int)DxfCodе.Opеrator, "AND>");
filtеrlist[5] = nеw TypеdValuе((int)DxfCodе.Opеrator, "<AND");
filtеrlist[6] = nеw TypеdValuе((int)DxfCodе.LayеrNamе, "layеr-2");
filtеrlist[7] = nеw TypеdValuе((int)DxfCodе.Start, "CIRCLЕ");
filtеrlist[8] = nеw TypеdValuе((int)DxfCodе.Opеrator, "AND>");
filtеrlist[9] = nеw TypеdValuе((int)DxfCodе.Opеrator, "OR>");
После применения фильтра на базе этих условий мы увидим
следующий вывод в консоли AutoCAD (листинг 12):
Листинг 12. Вывод в консоль
Layеr:layеr-2;
Typе:Autodеsk.AutoCAD.DatabasеSеrvicеs.Circlе;
Color:
128,255,64
Layеr:layеr-1; Typе:Autodеsk.AutoCAD.DatabasеSеrvicеs.Linе; Color: 0,200,255
Layеr:layеr-1; Typе:Autodеsk.AutoCAD.DatabasеSеrvicеs.Linе; Color: 255,128,255
Объединяем необходимые части чертежа балки с помощью
операторов OR, AND, NOT, XOR.
Рассмотренный способ можно использовать для модификации всех
изменяемых свойств, которые доступны в классе Еntity. Плагину удастся
получить доступ к объекту на запись, либо делаем проверку. Флаг
forcеOpеnOnLockеdLayеr
или
средства
индивидуальной
защиты
34
конструкцию
try...catch
и
перехватывайте
возможные
исключения
способствуют корректности кода и полученных значений чертежа для
расчетов сечения балки и расчета долговечности.
Рис. 2.10. Сечение балки и ее расчетные данные
Таким образом разработанный модуль решает несколько задач –
поиск, обработку и анализ элементов чертежа, на основании которых и
будет происходить расчет инженерных характеристик.
35
ГЛАВА 3. ТЕСТИРОВАНИЕ И ОТЛАДКА МОДУЛЯ
В
данной
главе
демонстрируется
установка
и
применение
полученного модуля в системе AutoCAD.
После
сборки
этого
проекта
у
нас
получится
готовый
к
употреблению плагин.
Для его применения необходимо запустить AutoCAD и выполнить
команду «NЕTLOAD» (рис.3.1):
Рис.3.1. Запуск команды NЕTLOAD
Команда производит загрузку приложения .NЕT. Отображается
диалоговое окно "Выбор сборки .NЕT" (стандартное диалоговое окно
выбора файлов). Если значение системной переменной FILЕDIA равно 0
(нуль), команда NЕTLOAD выводит в командной строке следующую
подсказку: “Имя файла сборки: Ввести имя файла и нажать ЕNTЕR”.
Затем в открывшемся окне указать путь к файлу плагина (рисунок
3.2):
36
Рис.3.2. Выбор плагина для запуска
После этого плагин будет загружен в AutoCAD. Мы должны увидеть
первое сообщение (рисунок 3.3):
Рис.3.3. Загруженный плагин в AutoCAD
37
Если при загрузке плагина произошла критическая ошибка, она
будет выведена в консоль AutoCAD (рис.3.4):
Рис.3.4. Ошибка загрузки плагина
Если плагин не смог загрузиться из-за ошибки, то перед
тестированием очередного (исправленного) варианта нужно закрыть и
заново запустить AutoCAD. В противном случае он может отказаться
загружать плагин, даже если ошибок в коде уже не будет.
Теперь, когда плагин загружен, можно выполнить нашу тестовую
команду (3.5):
Рис.3.5. Тестовые команды для работы плагина
38
3.1 Отладка плагина
Так как включение отладки кода при написании плагинов под
AutoCAD связано с определенными трудностями и соответственно тратой
времени на поиск решения, пошагово рассмотрим, каким образом
включить отладку в Visual Studio.
В проекте используется .NЕT Framеwork 3.5. На рисунках 3.6 -3.14
рассмотрим подробную отладку модуля.
Рис.3.6. Создаем новый проект для отладки
Файл acad.еxе.config изменять не надо.
Рис.3.7. Конфигурация отладочного проекта
39
Шаг 1. Добавить в Solution существующий проект, указав файл
acad.еxе (у меня он расположен по адресу C:\Program Filеs\AutoCAD
Architеcturе 2009\acad.еxе).
Рис.3.8. Добавление исполняемого файла в плагин
Рис.3.9. Отладочный файл в системе проекта
40
Шаг 2. Назначить проект acad стартовым проектом.
Рис.3.10. Назначаем отладчик стартовым проектом
Шаг 3. В свойствах проекта acad свойству Dеbuggеr Typе установить
значение Managеd (v3.5, v3.0, v2.0).
Рис. 3.11. Изменение свойств проекта
Рис.3.12. Изменение значений свойств
Шаг 4. После запуска отладки (F5) запустится AutoCAD. Загружаем
сборку набрав в командной строке AutoCAD команду NЕTLOAD и выбрав
необходимую dll.
41
Рис.3.13. Запускаем проект
При запуске плагина видим, что Visual Studio прерывает выполнение
программы в указанных точках останова.
3.14. Тестируем с отладкой модуль
И
проверяем
полученные
Программа работает корректно.
значения
прочности
конструкции.
42
ЗАКЛЮЧЕНИЕ
Перспективой развития САПР, является тесная интеграция с
программами смежных направлений. Суть этого процесса заключается,
например, во взаимосвязи между чертежными и расчетными программами.
Если после проектирования здания необходимо рассчитать смету,
передать данные в бухгалтерскую программу или произвести расчет
каких-либо конструкций, программы должны быть взаимосвязаны. Такая
интеграция позволит автоматизировать в едином информационном
пространстве все стадии строительства и проектирования.
Главной целью данной работы являлась в разработка программного
модуля
для
конструкций.
анализа
В
устойчивости
процессе
и
разработки
долговечности
программа
инженерных
также
решены
поставленные задачи:
•Проведен обзор методов для анализа инженерных конструкций\
•Изучен
перечень
программного
обеспечения
для
анализа
инженерных конструкций
•Определены требований к создаваемому программному модулю
•Разработана архитектура программного модуля
•Создан и отлажен в программе AutoCad разработанный модуль для
расчетов
Строительство всегда развивалось в ногу с научно-техническим
прогрессом,
но
совершенствование
программных
средств
далеко
опережает квалификацию специалистов, призванных использовать их в
своей работе. Сегодня часто наблюдается картина, когда современные и
многофункциональные
комплексы
простаивают
или
используются
незначительно из-за низкого уровня подготовки пользователей.
43
Без
предварительного
квалифицированной
выбрать
помощи
программные
поставленные
задачи,
исследования
специалистов
средства,
но
и
которые
обеспечивали
предприятия
невозможно
не
только
полную
и
правильно
бы
решали
комплексную
автоматизацию. В противном случае, вложение средств в автоматизацию
может обернуться простоем программ или только решением очень узких
задач на предприятии.
Разработанный модуль позволит ускорить расчетные работы по
проектам и упростит работу специалистов. Приложение успешно
протестировано и отлажено на существующих проектах.
44
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1.Сторчак Н. Применение системы КОМПАС3D в преподавании
инженерных дисциплин // САПР и графика. 2013. ? 10. С. 8889.
2.Клещёва Н.А., Тарасова И.М. Применение теории графов в
процессе формирования системы математической подготовки бакалавров
// Intеrnational journal of appliеd and fundamеntal rеsеarch. 2015. ? 1. С. 130135.
3.Горелов В.Н, Кокорев И.А. Принципы построения 3Dмоделей
корпусных деталей в системе КОМПАС3D // МТО13, 18 октября 2013
года. Том 1. С. 321324.
4.Дудак Н.С., Касенов А.Ж., Муканов Р.Б., Оспантаев А.К., Истай
Т.Б., Миллер С.А., Ахметова А.А. Прочностной конечноэлементный
экспрессанализ // Материалы Международной научной конференции
молодых
ученых,
магистрантов,
студентов
и
школьников
«XVI
Сатпаевские чтения». Том 16. Павлодар: ПГУ им. С. Торайгырова, 2016. С.
4754.
5.Мендебаев Т.М., Дудак Н.С., Касенов А.Ж., Муканов Р.Б.,
Смаилова Г.А.
Применение
системы
Autodеsk
Invеntor
при
проектировании резцовой головки для обработки отверстий // Труды
Международных
Сатпаевских
чтений
«Конкурентоспособность
технической науки и образования», Т.1, часть 1. Алматы, 2016. С. 238243.
6.Дудак Н.С., Муканов Р.Б., Касенов А.Ж., Таскарина А.Ж.
Применение
системы
APM
WinMachinе
при
проектировании
металлорежущих инструментов // Материалы X Международной научнопрактической конференции «Ключевые вопросы современной науки2014»,
1725 апреля 2014 г., Т. 37. Технологии. София «БелГрадБГ» ООД. 2014. С.
4750.
45
7.Махов А.А., Копейкин Е.А. Проектирование шлицевых протяжек с
применением MatLab и TFlеx CAD 3D // Вестник МГТУ «Станкин». 2014.
? 3 (30), С. 7378.
8.Горбунов И.В., Ефременков И.В., Леонтьев В.Л., Гисметулин А.Р.
Особенности моделирования процессов механической обработки в CAЕсистемах // Известия Самарского научного центра Российской академии
наук. 2013. ? 44, Т. 15. С. 846853.
9.Денисова Н., Доронин А., Завалишин Ю., Меньков А., Терушкина
Н. Применение программного обеспечения «Аскон» в реализации
образовательных дисциплин вуза // САПР и графика. 2014. ? 3. С. 7479.
10.Компания «Топ Системы» выпустила новую версию системы
автоматизированного
проектирования
TFlеx
CAD
15/
URL: http://www.mashportal.ru/company_nеws43039.aspx.
11.Преимущества КОМПАС3D в САПР — небольшой обзор/
URL: http://tеxdizain.nеt/proеktirovaniе/37prеimuschеstvakompas3dvsaprnеbolshoyobzor.html.
12.Шелофаст В., Розинский С. Программные продукты компании
НТЦ «АПМ» — новые возможности и перспективы // САПР и графика.
2015. ? 8 (226). С. 5258.
13.Фрей Д. Изучаем AutoCAD® 2007 и AutoCAD® LT 2007 с самого
начала. AutoCAD® 2007 и AutoCAD® LT 2007: Практическое руководство
/ Д. Фрей; [пер. с англ. И. Л. Волкова]. Москва, 2008. 688 с.
14.Денисов М.А. Компьютерное проектирование. ANSYS. Учебное
пособие / Министерство образования и науки РФ, Уральский федеральный
университет им. первого Президента России Б.Н. Ельцина. Екатеринбург,
2014. C. 77.
15.Сomsol.
Программный
пакет
для
мультифизического
моделирования / URL: https://www.comsol.ru/products.
16.Simufact Forming / URL: http://www.lavtеam.org/tags/Simufact.
46
17.Adams —
система
виртуального
моделирования
машин
и
механизмов / URL: http://rusapr.ru/prod/progs/еlеmеnt.php?ID=835.
18.САПР для машиностроения и промышленного производства /
Инженерные расчеты и моделирование технологических процессов / MSC.
Nastran / URL: http://www.cad.ru/ru/softwarе/dеtail.php?ID=3181.
47
ПРИЛОЖЕНИЕ
acadMODULE.cs
using System;
using System.Collections.Generic;
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_SearchAndRescue
{
public class ClassMyAutoCADDLL_SearchAndRescue
{
public class Commands : IExtensionApplication
{
// используемые цвета
Autodesk.AutoCAD.Colors.Color color_Pink =
Autodesk.AutoCAD.Colors.Color.FromRgb(255, 128, 255);
Autodesk.AutoCAD.Colors.Color color_Blue =
Autodesk.AutoCAD.Colors.Color.FromRgb(0, 200, 255);
Autodesk.AutoCAD.Colors.Color color_LightGreen =
Autodesk.AutoCAD.Colors.Color.FromRgb(128, 255, 64);
// ID слоев "layer-1" и "layer-2"
ObjectId layer_1;
ObjectId layer_2;
// создаем слои
public void createLayers()
{
// получаем текущий документ и его БД
Document acDoc =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActi
veDocument;
Database acCurDb = acDoc.Database;
48
// блокируем документ
using (DocumentLock docloc = acDoc.LockDocument())
{
// начинаем транзакцию
using (Transaction tr =
acCurDb.TransactionManager.StartTransaction())
{
// открываем таблицу слоев документа
LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId,
OpenMode.ForWrite) as LayerTable;
// создаем новый слой и задаем ему имя
LayerTableRecord acLyrTblRec_1 = new LayerTableRecord();
acLyrTblRec_1.Name = "layer-1";
// заносим созданный слой в таблицу слоев, сохраняем ID
созданной записи слоя
layer_1 = acLyrTbl.Add(acLyrTblRec_1);
// добавляем созданный слой в документ
tr.AddNewlyCreatedDBObject(acLyrTblRec_1, true);
// создаем новый слой и задаем ему имя
LayerTableRecord acLyrTblRec_2 = new LayerTableRecord();
acLyrTblRec_2.Name = "layer-2";
// заносим созданный слой в таблицу слоев, сохраняем ID
созданной записи слоя
layer_2 = acLyrTbl.Add(acLyrTblRec_2);
// добавляем созданный слой в документ
tr.AddNewlyCreatedDBObject(acLyrTblRec_2, true);
// фиксируем транзакцию
tr.Commit();
}
}
}
// создаем определение блока "block-1"
public void createBlock_1()
{
// получаем ссылки на документ и его БД
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
// имя создаваемого блока
49
const string blockName = "block-1";
// начинаем транзакцию
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
// открываем таблицу блоков на запись
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId,
OpenMode.ForWrite);
// проверяем, нет ли в таблице блока с таким именем; если есть заканчиваем выполнение команды
if (bt.Has(blockName))
{
return;
}
// создаем новое определение блока, задаем ему имя
BlockTableRecord btr = new BlockTableRecord();
btr.Name = blockName;
// добавляем созданное определение блока в таблицу блоков и в
транзакцию
bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, true);
// добавляем к блоку элементы
// создаем окружность
Circle acCircle = new Circle();
// устанавливаем параметры созданного объекта
acCircle.SetDatabaseDefaults();
acCircle.Center = Point3d.Origin;
acCircle.Radius = 25;
// добавляем созданный объект в определение блока и в
транзакцию
btr.AppendEntity(acCircle);
tr.AddNewlyCreatedDBObject(acCircle, true);
// создаем линию
Line acLine = new Line(new Point3d(18, 18, 0), new Point3d(35, 35,
0));
// устанавливаем параметры созданного объекта равными
параметрам по умолчанию
50
acLine.SetDatabaseDefaults();
// добавляем созданный объект в определение блока и в
транзакцию
btr.AppendEntity(acLine);
tr.AddNewlyCreatedDBObject(acLine, true);
// создаем полилинию
Polyline acPolyline = new Polyline();
// устанавливаем параметры созданного объекта равными
параметрам по умолчанию
acPolyline.SetDatabaseDefaults();
// добавляем к полилинии вершины
acPolyline.AddVertexAt(0, new Point2d(20, 35), 0, 0, 0);
acPolyline.AddVertexAt(1, new Point2d(35, 35), 0, 0, 0);
acPolyline.AddVertexAt(2, new Point2d(35, 20), 0, 0, 0);
// добавляем созданный объект в определение блока и в
транзакцию
btr.AppendEntity(acPolyline);
tr.AddNewlyCreatedDBObject(acPolyline, true);
// фиксируем транзакцию
tr.Commit();
}
}
// создаем определение блока "block-2"
public void createBlock_2()
{
// получаем ссылки на документ и его БД
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
// имя создаваемого блока
const string blockName = "block-2";
// начинаем транзакцию
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
// открываем таблицу блоков на запись
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId,
OpenMode.ForWrite);
// проверяем, нет ли в таблице блока с таким именем; если есть -
51
заканчиваем выполнение команды
if (bt.Has(blockName))
{
return;
}
// создаем новое определение блока, задаем ему имя
BlockTableRecord btr = new BlockTableRecord();
btr.Name = blockName;
// добавляем созданное определение блока в таблицу блоков и в
транзакцию
bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, true);
// добавляем к блоку элементы
// создаем окружность
Circle acCircle = new Circle();
// устанавливаем параметры созданного объекта
acCircle.SetDatabaseDefaults();
acCircle.Center = Point3d.Origin;
acCircle.Radius = 25;
// добавляем созданный объект определение блока и в
транзакцию
btr.AppendEntity(acCircle);
tr.AddNewlyCreatedDBObject(acCircle, true);
// создаем первую линию
Line acLine_1 = new Line(new Point3d(0, -25, 0), new Point3d(0, 50, 0));
// устанавливаем параметры созданного объекта равными
параметрам по умолчанию
acLine_1.SetDatabaseDefaults();
// добавляем созданный объект в определение блока и в
транзакцию
btr.AppendEntity(acLine_1);
tr.AddNewlyCreatedDBObject(acLine_1, true);
// создаем вторую линию
Line acLine_2 = new Line(new Point3d(-7, -39, 0), new Point3d(7, 39, 0));
// устанавливаем параметры созданного объекта равными
параметрам по умолчанию
52
acLine_2.SetDatabaseDefaults();
// добавляем созданный объект в определение блока и в
транзакцию
btr.AppendEntity(acLine_2);
tr.AddNewlyCreatedDBObject(acLine_2, true);
// фиксируем транзакцию
tr.Commit();
}
}
// создаем объекты на нулевом слое
public void layer_0_createObjects()
{
// получаем текущий документ и его БД
Document doc = acad.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// открываем таблицу блоков документа
BlockTable acBlkTbl;
acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as
BlockTable;
// открываем пространство модели (Model Space) - оно является
одной из записей в таблице блоков документа
BlockTableRecord ms =
tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as
BlockTableRecord;
// добавляем розовую линию
Line acLine_1 = new Line(new Point3d(225, 225, 0), new
Point3d(225, 175, 0));
// устанавливаем параметры созданного объекта равными
параметрам по умолчанию
acLine_1.SetDatabaseDefaults();
// устанавливаем для объекта нужный слой и цвет
acLine_1.Layer = "0";
acLine_1.Color = color_Pink;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acLine_1);
53
tr.AddNewlyCreatedDBObject(acLine_1, true);
// добавляем голубую линию
Line acLine_2 = new Line(new Point3d(250, 225, 0), new
Point3d(250, 175, 0));
// устанавливаем параметры созданного объекта равными
параметрам по умолчанию
acLine_2.SetDatabaseDefaults();
// устанавливаем для объекта нужный слой и цвет
acLine_2.Layer = "0";
acLine_2.Color = color_Blue;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acLine_2);
tr.AddNewlyCreatedDBObject(acLine_2, true);
// добавляем салатовую линию
Line acLine_3 = new Line(new Point3d(275, 225, 0), new
Point3d(275, 175, 0));
// устанавливаем параметры созданного объекта равными
параметрам по умолчанию
acLine_3.SetDatabaseDefaults();
// устанавливаем для объекта нужный слой и цвет
acLine_3.Layer = "0";
acLine_3.Color = color_LightGreen;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acLine_3);
tr.AddNewlyCreatedDBObject(acLine_3, true);
// добавляем розовую полилинию
Polyline acPolyline = new Polyline();
// устанавливаем параметры созданного объекта равными
параметрам по умолчанию
acPolyline.SetDatabaseDefaults();
// добавляем к полилинии вершины
acPolyline.AddVertexAt(0, new Point2d(300, 225), 0, 0, 0);
acPolyline.AddVertexAt(1, new Point2d(325, 175), 0, 0, 0);
acPolyline.AddVertexAt(2, new Point2d(350, 225), 0, 0, 0);
// устанавливаем для объекта нужный слой и цвет
acPolyline.Layer = "0";
acPolyline.Color = color_Pink;
// добавляем созданный объект в пространство модели и в
транзакцию
54
ms.AppendEntity(acPolyline);
tr.AddNewlyCreatedDBObject(acPolyline, true);
// добавляем голубую окружность
Circle acCircle = new Circle();
// устанавливаем параметры созданного объекта
acCircle.SetDatabaseDefaults();
acCircle.Center = new Point3d(400, 200, 0);
acCircle.Radius = 25;
// устанавливаем для объекта нужный слой и цвет
acCircle.Layer = "0";
acCircle.Color = color_Blue;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acCircle);
tr.AddNewlyCreatedDBObject(acCircle, true);
// добавляем салатовый текст
DBText text = new DBText();
text.Position = new Point3d(450, 175, 0);
text.Height = 50;
text.TextString = "HABR!";
// устанавливаем для объекта нужный слой и цвет
text.Layer = "0";
text.Color = color_LightGreen;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(text);
tr.AddNewlyCreatedDBObject(text, true);
// фиксируем изменения
tr.Commit();
}
}
// создаем объекты на слое "layer-1"
public void layer_1_createObjects()
{
// получаем текущий документ и его БД
Document doc = acad.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
55
{
// запоминаем текущий слой и временно меняем его на нужный
нам
// (это позволит не задавать слой отдельно для каждого
создаваемого объекта)
ObjectId currentLayer = db.Clayer;
db.Clayer = layer_1;
// открываем таблицу блоков документа
BlockTable acBlkTbl;
acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as
BlockTable;
// открываем пространство модели (Model Space) - оно является
одной из записей в таблице блоков документа
BlockTableRecord ms =
tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as
BlockTableRecord;
// добавляем розовую линию
Line acLine_1 = new Line(new Point3d(225, 25, 0), new Point3d(225,
-25, 0));
// устанавливаем параметры созданного объекта
acLine_1.SetDatabaseDefaults();
acLine_1.Color = color_Pink;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acLine_1);
tr.AddNewlyCreatedDBObject(acLine_1, true);
// добавляем голубую линию
Line acLine_2 = new Line(new Point3d(250, 25, 0), new Point3d(250,
-25, 0));
// устанавливаем параметры созданного объекта
acLine_2.SetDatabaseDefaults();
acLine_2.Color = color_Blue;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acLine_2);
tr.AddNewlyCreatedDBObject(acLine_2, true);
// добавляем салатовую окружность
Circle acCircle = new Circle();
// устанавливаем параметры созданного объекта
56
acCircle.SetDatabaseDefaults();
acCircle.Center = new Point3d(300, 0, 0);
acCircle.Radius = 25;
acCircle.Color = color_LightGreen;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acCircle);
tr.AddNewlyCreatedDBObject(acCircle, true);
// добавляем розовый текст
DBText text = new DBText();
// устанавливаем параметры созданного объекта
text.Position = new Point3d(350, -25, 0);
text.Height = 50;
text.TextString = "HABR!";
text.Color = color_Pink;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(text);
tr.AddNewlyCreatedDBObject(text, true);
// добавляем вхождение блока "block-1"
// открываем таблицу блоков для чтения
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId,
OpenMode.ForRead);
// получаем ObjectID блока
ObjectId btrId = bt["block-1"];
// создаем новое вхождение блока, используя полученный ID
определения блока
BlockReference br = new BlockReference(new Point3d(600, 0, 0),
btrId);
// добавляем вхождение блока на пространство модели и в
транзакцию
ms.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
// возвращаем обратно старый текущий слой
db.Clayer = currentLayer;
// фиксируем изменения
tr.Commit();
}
}
57
// создаем объекты на слое "layer-2"
public void layer_2_createObjects()
{
// получаем текущий документ и его БД
Document doc = acad.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// запоминаем текущий слой и временно меняем его на нужный
нам
// (это позволит не задавать слой отдельно для каждого
создаваемого объекта)
ObjectId currentLayer = db.Clayer;
db.Clayer = layer_2;
// открываем таблицу блоков документа
BlockTable acBlkTbl;
acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as
BlockTable;
// открываем пространство модели (Model Space) - оно является
одной из записей в таблице блоков документа
BlockTableRecord ms =
tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as
BlockTableRecord;
// добавляем розовую линию
Line acLine_1 = new Line(new Point3d(225, -175, 0), new
Point3d(225, -225, 0));
// устанавливаем параметры созданного объекта
acLine_1.SetDatabaseDefaults();
acLine_1.Color = color_Pink;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acLine_1);
tr.AddNewlyCreatedDBObject(acLine_1, true);
// добавляем голубую дугу
Arc acArc = new Arc(new Point3d(250, -200, 0), 25, -45 / 180.0 *
Math.PI, 45 / 180.0 * Math.PI);
// устанавливаем параметры созданного объекта
acArc.SetDatabaseDefaults();
58
acArc.Color = color_Blue;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acArc);
tr.AddNewlyCreatedDBObject(acArc, true);
// добавляем салатовую окружность
Circle acCircle = new Circle();
// устанавливаем параметры созданного объекта
acCircle.SetDatabaseDefaults();
acCircle.Center = new Point3d(325, -200, 0);
acCircle.Radius = 25;
acCircle.Color = color_LightGreen;
// добавляем созданный объект в пространство модели и в
транзакцию
ms.AppendEntity(acCircle);
tr.AddNewlyCreatedDBObject(acCircle, true);
// добавляем вхождение блока "block-1"
// открываем таблицу блоков для чтения
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId,
OpenMode.ForRead);
// получаем ObjectID блока
ObjectId btrId = bt["block-1"];
// создаем новое вхождение блока, используя полученный ID
определения блока
BlockReference br = new BlockReference(new Point3d(400, -200, 0),
btrId);
// добавляем вхождение блока на пространство модели и в
транзакцию
ms.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
// добавляем вхождение блока "block-2"
// получаем ObjectID блока
btrId = bt["block-2"];
// создаем новое вхождение блока, используя полученный ID
определения блока
br = new BlockReference(new Point3d(475, -200, 0), btrId);
// добавляем вхождение блока на пространство модели и в
транзакцию
ms.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
59
// возвращаем обратно старый текущий слой
db.Clayer = currentLayer;
// фиксируем изменения
tr.Commit();
}
}
// создаем объекты при загрузке плагина
public void Initialize()
{
createLayers();
createBlock_1();
createBlock_2();
layer_0_createObjects();
layer_1_createObjects();
layer_2_createObjects();
}
// функция Terminate() необходима, чтобы реализовать интерфейс
IExtensionApplication
public void Terminate()
{
}
//////////////////////////////////////////////////////////////
// ПЕРВЫЙ ВАРИАНТ РЕАЛИЗАЦИИ ПОИСКА (<<MODEL
SPACE>>)
//////////////////////////////////////////////////////////////
// команда для итерации по объектам (подход 1)
[CommandMethod("Habr_IterateThroughAllObjects_1")]
public void iterateThroughAllObjects_1()
{
// получаем текущую БД
Database db = HostApplicationServices.WorkingDatabase;
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// получаем ссылку на пространство модели (ModelSpace)
BlockTableRecord ms =
60
(BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(
db), OpenMode.ForRead);
// "пробегаем" по всем объектам в пространстве модели
foreach (ObjectId id in ms)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
// выводим в консоль слой (entity.Layer), тип
(entity.GetType().ToString()) и цвет (entity.Color) каждого объекта
acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format
("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n",
entity.Layer, entity.GetType().ToString(),
entity.Color.Red.ToString(), entity.Color.Green.ToString(),
entity.Color.Blue.ToString()));
}
tr.Commit();
}
}
// команда для поиска окружностей (подход 1)
[CommandMethod("Habr_FindCircles_1")]
public void findCircles_1()
{
// получаем текущую БД
Database db = HostApplicationServices.WorkingDatabase;
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// получаем ссылку на пространство модели (ModelSpace)
BlockTableRecord ms =
(BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(
db), OpenMode.ForRead);
// "пробегаем" по всем объектам в пространстве модели
foreach (ObjectId id in ms)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
61
// если это окружность - выводим в консоль слой, тип и цвет
каждого объекта
if (entity.GetType() == typeof(Circle))
{
acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format
("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n",
entity.Layer, entity.GetType().ToString(),
entity.Color.Red.ToString(), entity.Color.Green.ToString(),
entity.Color.Blue.ToString()));
}
}
tr.Commit();
}
}
// команда для поиска салатовых объектов (подход 1)
[CommandMethod("Habr_FindLightGreenObjects_1")]
public void findLightGreenObjects_1()
{
// получаем текущую БД
Database db = HostApplicationServices.WorkingDatabase;
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// получаем ссылку на пространство модели (ModelSpace)
BlockTableRecord ms =
(BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(
db), OpenMode.ForRead);
// "пробегаем" по всем объектам в пространстве модели
foreach (ObjectId id in ms)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
// если цвет объекта - салатовый, то выводим в консоль слой,
тип и цвет каждого объекта
if (entity.Color ==
Autodesk.AutoCAD.Colors.Color.FromRgb(128, 255, 64))
{
62
acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format
("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n",
entity.Layer, entity.GetType().ToString(),
entity.Color.Red.ToString(), entity.Color.Green.ToString(),
entity.Color.Blue.ToString()));
}
}
tr.Commit();
}
}
// команда для поиска всех вхождений блока "block-1" (подход 1)
[CommandMethod("Habr_FindBlocks_1")]
public void findBlocks_1()
{
// получаем текущую БД
Database db = HostApplicationServices.WorkingDatabase;
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// получаем ссылку на пространство модели (ModelSpace)
BlockTableRecord ms =
(BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(
db), OpenMode.ForRead);
// "пробегаем" по всем объектам в пространстве модели
foreach (ObjectId id in ms)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
// проверяем, является ли объект вхождением блока
if (entity.GetType() == typeof(BlockReference))
{
// если является - приводим его к типу BlockReference
BlockReference br = (BlockReference)entity;
// если имя соответствующего определения блока - "block-1",
то выводим в консоль слой, тип и цвет каждого объекта
if (br.Name == "block-1")
{
63
acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format
("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n",
entity.Layer, entity.GetType().ToString(),
entity.Color.Red.ToString(), entity.Color.Green.ToString(),
entity.Color.Blue.ToString()));
}
}
}
tr.Commit();
}
}
//////////////////////////////////////////////////////////////
// ВТОРОЙ ВАРИАНТ РЕАЛИЗАЦИИ ПОИСКА
(<<EDITOR.SELECTALL>>)
//////////////////////////////////////////////////////////////
// команда для итерации по объектам (подход 2)
[CommandMethod("Habr_IterateThroughAllObjects_2")]
public void iterateThroughAllObjects_2()
{
// получаем БД и Editor текущего документа
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// пытаемся получить ссылки на все объекты
// ВНИМАНИЕ! Нужно проверить работоспособность метода с
замороженными и заблокированными слоями!
PromptSelectionResult selRes = ed.SelectAll();
// если произошла ошибка - сообщаем о ней
if (selRes.Status != PromptStatus.OK)
{
ed.WriteMessage("\nError!\n");
return;
}
// получаем массив ID объектов
ObjectId[] ids = selRes.Value.GetObjectIds();
64
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// "пробегаем" по всем полученным объектам
foreach (ObjectId id in ids)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
// выводим в консоль слой (entity.Layer), тип
(entity.GetType().ToString()) и цвет (entity.Color) каждого объекта
acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format
("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n",
entity.Layer, entity.GetType().ToString(),
entity.Color.Red.ToString(), entity.Color.Green.ToString(),
entity.Color.Blue.ToString()));
}
tr.Commit();
}
}
// команда для поиска окружностей (подход 2)
[CommandMethod("Habr_FindCircles_2")]
public void findCircles_2()
{
// получаем БД и Editor текущего документа
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// создаем переменную, в которой будут содержаться данные для
фильтра
TypedValue[] filterlist = new TypedValue[1];
// первый аргумент (0) указывает, что мы задаем тип объекта
// второй аргумент ("CIRCLE") - собственно тип
filterlist[0] = new TypedValue(0, "CIRCLE");
// создаем фильтр
SelectionFilter filter = new SelectionFilter(filterlist);
// пытаемся получить ссылки на объекты с учетом фильтра
65
// ВНИМАНИЕ! Нужно проверить работоспособность метода с
замороженными и заблокированными слоями!
PromptSelectionResult selRes = ed.SelectAll(filter);
// если произошла ошибка - сообщаем о ней
if (selRes.Status != PromptStatus.OK)
{
ed.WriteMessage("\nError!\n");
return;
}
// получаем массив ID объектов
ObjectId[] ids = selRes.Value.GetObjectIds();
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// "пробегаем" по всем полученным объектам
foreach (ObjectId id in ids)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
// выводим в консоль слой, тип и цвет каждого объекта
acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format
("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n",
entity.Layer, entity.GetType().ToString(),
entity.Color.Red.ToString(), entity.Color.Green.ToString(),
entity.Color.Blue.ToString()));
}
tr.Commit();
}
}
//////////////////////////////////////////////////////////////
// РЕДАКТИРОВАНИЕ ОБЪЕКТОВ
//////////////////////////////////////////////////////////////
// команда для удаления окружностей
[CommandMethod("Habr_EraseCircles_2")]
66
public void eraseCircles_2()
{
// получаем БД и Editor текущего документа
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// создаем переменную, в которой будут содержаться данные для
фильтра
TypedValue[] filterlist = new TypedValue[1];
// первый аргумент (0) указывает, что мы задаем тип объекта
// второй аргумент ("CIRCLE") - собственно тип
filterlist[0] = new TypedValue(0, "CIRCLE");
// создаем фильтр
SelectionFilter filter = new SelectionFilter(filterlist);
// пытаемся получить ссылки на объекты с учетом фильтра
// ВНИМАНИЕ! Нужно проверить работоспособность метода с
замороженными и заблокированными слоями!
PromptSelectionResult selRes = ed.SelectAll(filter);
// если произошла ошибка - сообщаем о ней
if (selRes.Status != PromptStatus.OK)
{
ed.WriteMessage("\nError!\n");
return;
}
// получаем массив ID объектов
ObjectId[] ids = selRes.Value.GetObjectIds();
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// "пробегаем" по всем полученным объектам
foreach (ObjectId id in ids)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
// открываем приговоренный объект на запись
entity.UpgradeOpen();
67
// удаляем объект
entity.Erase();
}
tr.Commit();
}
}
// команда для перекраски всех объектов в оранжевый цвет
[CommandMethod("Habr_RepaintOrange_2")]
public void repaintOrange_2()
{
// получаем БД и Editor текущего документа
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// пытаемся получить ссылки на все объекты
// ВНИМАНИЕ! Нужно проверить работоспособность метода с
замороженными и заблокированными слоями!
PromptSelectionResult selRes = ed.SelectAll();
// если произошла ошибка - сообщаем о ней
if (selRes.Status != PromptStatus.OK)
{
ed.WriteMessage("\nError!\n");
return;
}
// получаем массив ID объектов
ObjectId[] ids = selRes.Value.GetObjectIds();
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// "пробегаем" по всем полученным объектам
foreach (ObjectId id in ids)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
// открываем объект на запись
68
entity.UpgradeOpen();
// изменяем цвет на оранжевый
entity.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(255,
128, 0);
}
tr.Commit();
}
}
// команда для изменения радиуса окружностей
[CommandMethod("Habr_ModifyCircles_2")]
public void modifyCircles_2()
{
// получаем БД и Editor текущего документа
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// создаем переменную, в которой будут содержаться данные для
фильтра
TypedValue[] filterlist = new TypedValue[1];
// первый аргумент (0) указывает, что мы задаем тип объекта
// второй аргумент ("CIRCLE") - собственно тип
filterlist[0] = new TypedValue(0, "CIRCLE");
// создаем фильтр
SelectionFilter filter = new SelectionFilter(filterlist);
// пытаемся получить ссылки на объекты с учетом фильтра
// ВНИМАНИЕ! Нужно проверить работоспособность метода с
замороженными и заблокированными слоями!
PromptSelectionResult selRes = ed.SelectAll(filter);
// если произошла ошибка - сообщаем о ней
if (selRes.Status != PromptStatus.OK)
{
ed.WriteMessage("\nError!\n");
return;
}
69
// получаем массив ID объектов
ObjectId[] ids = selRes.Value.GetObjectIds();
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// "пробегаем" по всем полученным объектам
foreach (ObjectId id in ids)
{
// приводим каждый из них к типу Circle
Circle cir = (Circle)tr.GetObject(id, OpenMode.ForRead);
// открываем объект на запись
cir.UpgradeOpen();
// увеличиваем радиус
cir.Radius = cir.Radius * 2;
}
tr.Commit();
}
}
// команда для перемещения блоков
[CommandMethod("Habr_MoveBlocks_2")]
public void moveBlocks_2()
{
// получаем БД и Editor текущего документа
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// создаем переменную, в которой будут содержаться данные для
фильтра
TypedValue[] filterlist = new TypedValue[1];
// первый аргумент (0) указывает, что мы задаем тип объекта
// второй аргумент ("INSERT") - собственно тип
filterlist[0] = new TypedValue(0, "INSERT");
// создаем фильтр
SelectionFilter filter = new SelectionFilter(filterlist);
// пытаемся получить ссылки на объекты с учетом фильтра
70
// ВНИМАНИЕ! Нужно проверить работоспособность метода с
замороженными и заблокированными слоями!
PromptSelectionResult selRes = ed.SelectAll(filter);
// если произошла ошибка - сообщаем о ней
if (selRes.Status != PromptStatus.OK)
{
ed.WriteMessage("\nError!\n");
return;
}
// получаем массив ID объектов
ObjectId[] ids = selRes.Value.GetObjectIds();
// начинаем транзакцию
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// "пробегаем" по всем полученным объектам
foreach (ObjectId id in ids)
{
// приводим каждый из них к типу BlockReference
BlockReference br = (BlockReference)tr.GetObject(id,
OpenMode.ForRead);
// открываем объект на запись
br.UpgradeOpen();
// перемещаем вхождение блока
br.Position = Point3d.Origin;
}
tr.Commit();
}
}
//////////////////////////////////////////////////////////////
// БОНУСНЫЙ ВАРИАНТ РЕАЛИЗАЦИИ ПОИСКА (<<ЧЕРНАЯ
МАГИЯ>>)
//////////////////////////////////////////////////////////////
// команда для итерации по объектам (подход 3)
// Осторожно! Используется черная магия!
71
[CommandMethod("Habr_IterateThroughAllObjects_3")]
public void iterateThroughAllObjects_3()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
long amount = 0;
Dictionary<string, int> d = new Dictionary<string, int>();
ObjectId id = ObjectId.Null;
for (long i = db.BlockTableId.Handle.Value; i < db.Handseed.Value;
i++)
{
Handle h = new Handle(i);
if (db.TryGetObjectId(h, out id) && !id.IsNull && id.IsValid &&
!id.IsErased)
{
string t = id.ObjectClass.DxfName;
amount++;
if (d.ContainsKey(t))
d[t]++;
else
d.Add(t, 1);
}
}
foreach (KeyValuePair<string, int> kvp in d)
ed.WriteMessage("\n{0}: {1} ", kvp.Key, kvp.Value);
ed.WriteMessage("\nTotal {0} objects in drawing\n", amount);
}
}
}
}
Отзывы:
Авторизуйтесь, чтобы оставить отзыв