3D моделирование в AutoCAD, в последнее время приобретает все большую популярность. Ряд неоспоримых преимуществ 3D моделирования привлекает к себе все большее количество сторонников.
Имея опыт в программном создание 2D объектов на языке LISP, я решил попробовать свои силы в 3D моделировании в AutoCAD.
В этом уроке мы создадим простой 3D объект – тройник и напишем программу вращения, позволяющую легко и быстро ориентировать 3D объект в пространстве. Идея создания 3D тройника принадлежит читателю моего сайта Рустему Вилевичу.
В конце статьи смотрите видео к этому уроку.
Пример LISP программы — Создание 3D объекта.
Откройте AutoCAD.
Для лучшей наглядности переведем чертеж ЮЗ изометрию. Для этого на видовом кубе щелкнуть между Ю и З в место, которое показано на Рис. 1.
Откройте редактор Visual LISP.
Введите в командной строке «VLIDE” (или «VLISP») и нажмите <Enter>.
Создайте новый файл.
Свой тройник я предполагаю сделать из еще более простых фигур цилиндров.
Поскольку цилиндры я буду создавать при помощи vla-функций, которые являются расширением языка AutoLISP, добавляем функцию, которая их загружает
(vl-load-com)
И указатели на все объекты более высокого уровня
В начале, нам нужно получить указатель на саму программу AutoCAD:
(setq acad_object (vlax-get-acad-object))
Указатель сохраняем в переменной acad_object.
Затем указатель на активный документ:
(setq active_document (vlax-get-activedocument acad_object))
Указатель сохраняем в переменной active_document.
И указатель пространства модели чертежа:
(setq model_space (vlax-get-modelspace active_document))
Указатель сохраняем в переменной model_space.
См. Рис. 2.
Добавим переменную R1, в которой будет хранить радиус первого (основного) цилиндра:
(setq R1 100)
Добавим переменную L1, в которой будет хранить длину первого (основного) цилиндра:
(setq L1 300)
Затем добавляем запрос базовой точки от которой мы начнем наши построения:
(getpoint "\nУкажите базовую точку : ")
Координаты базовой точки сохраняем в переменной bp:
(setq bp (getpoint "\nУкажите базовую точку : "))
См. Рис. 3.
Теперь у нас, есть все данные для того, чтобы построить цилиндр:
(vla-AddCylinder model_space (vlax-3D-point bp) R1 L1), где
model_space – указатель на пространство модели; bp – координаты базовой точки. vlax-3D-point – функция, которая создает из координат точки, точку типа Variant; R1 – радиус цилиндра; L1 – длина цилиндра.
vla-объект цилиндр сохраняем в переменной vla_cil:
(setq vla_cil (vla-AddCylinder model_space (vlax-3D-point bp) R1 L1))
Добавим, последнюю строчку. Выделяем весь текст и нажимаем на кнопку «Загрузить выделенный фрагмент». См. Рис. 4.
Программа перейдет в окно AutoCAD. В командной строке появится запрос: «Укажите базовую точку :». Укажите любую точку в рабочем окне AutoCAD. Программа построит цилиндр. См. Рис. 5.
Давайте теперь выделим наш цилиндр и посмотрим координаты центров нижней и верхней окружностей. Мы видим, что при длине цилиндра = 300, половина цилиндра от базовой точки построилась в низ (X, Y, —150), а другая половина вверх (X, Y, 150),. То есть, указанная нами базовая точка находится в середине отрезка, соединяющего эти центры (X, Y, 0). См. Рис. 6.
Теперь давайте повернем наш цилиндр вокруг прямой, параллельной оси Y и проходящей через нашу базовую точку, на 90 градусов. Для этого мы будем использовать функцию vla-Rotate3D, которая в общем виде выглядит так:
(vla-Rotate3D <vla_объект> <точка1 типа Variant > < точка2 типа Variant > <Угол>), где
<vla_объект> - вращаемый vla_объект; <точка1 типа Variant > < точка2 типа Variant > - точки прямой вокруг которой происходит вращение; <Угол > - величина угла поворота в радианах
Первая точка для прямой, вокруг которой происходит вращение, у нас уже есть – это наша базовая точка bp. Для того, чтобы прямая, вокруг которой происходит вращение, была параллельно оси Y, координаты второй точки должны отличаться от первой только координатой У.
Поэтому давайте, в начале разложим координаты первой точки.
(setq X1 (nth 0 bp)) – координата X базовой точки. (setq Y1 (nth 1 bp)) – координата Y базовой точки. (setq Z1 (nth 2 bp)) – координата Z базовой точки.
Затем изменим координату Y:
(setq Y2 (+ Y1 100))
И соберем координаты второй точки в новый список.
(list X1 Y2 Z1)
Сохраним координата второй точки в переменной p2:
(setq р2 (list X1 Y2 Z1))
Функция вращения vla-Rotate3D в нашей программе будет выглядеть, следующим образом:
(vla-Rotate3D vla_cil (vlax-3D-point bp) (vlax-3D-point p2)) (/ Pi 2))
Добавим эти строки в программу. См. Рис. 7.
Выделите их и нажмите на кнопку «Загрузить выделенный фрагмент». См. Рис. 8.
Цилиндр повернется. См. Рис. 9.
Теперь давайте построим второй цилиндр (ответвление).
Перед построением добавляем следующие строки:
Добавим переменную R2, в которой будет хранить радиус второго цилиндра (ответвления):
(setq R2 75)
Добавим переменную L2, в которой будет хранить длину ответвления:
(setq L2 100)
Поскольку, длина ответвления у нас задается от поверхности основного цилиндра, то к переменной L2 добавляем радиус R1. И сохраняем новую длину в переменной L21
(setq L21 (+ L2 R1))
Помня о том, что цилиндр строится от базовой точки половина вверх ,а половина вниз, заранее сдвигаем координату Z на половину новой длины вверх:
(setq Z12 (+ Z1 (/ L21 2)))
И наконец, строим второй цилиндр, сохраняя его в переменной vla_otv :
(setq vla_otv (vla-AddCylinder model_space (vlax-3D-point (list X1 Y1 Z12)) D2 L21))
Добавим эти строки в программу. См. Рис. 10.
Выделите их и нажмите на кнопку «Загрузить выделенный фрагмент». См. Рис. 11.
Программа построит второй цилиндр (ответвление). См. Рис. 12.
Следующий шаг – объединение цилиндров. Объединение мы будет делать при помощи функции command и стандартной команды Автокад _union.
Но предварительно преобразует наши vla-объекты цилиндры в обычные примитивы
(setq cil (vlax-vla-object->ename vla_cil)) - преобразует первый цилиндр в обычный примитив. (setq otv (vlax-vla-object->ename vla_otv)) - преобразует второй цилиндр в обычный примитив.
Строка объединяющая цилиндры выглядит так:
(command "_union" cil otv ""), где
cil – первый цилиндр; otv – второй цилиндр; “” – имитирует нажатие клавиши <Enter>.
Добавим эти строки в программу. См. Рис. 13.
Выделите их и нажмите на кнопку «Загрузить выделенный фрагмент». См. Рис. 14.
Программа объединит цилиндры и получим 3D тройник. См. Рис. 15.
Давайте посмотрим на наши построения спереди. Нажмите на видовом кубе грань «Перед» как показано на рис. 16.
Спереди наш тройник будет выглядит как на рис. 17.
Для того чтобы текущие привязки не влияли на построения, сгруппируем нашу программу по другому: все вычисления поднимем выше.
Перед функциями построения добавим строку
(setq osm (getvar "osmode")) , которая запоминает текущие привязки,
И строку
(setvar "osmode" 0) , которая отключает привязки.
А после функций построения добавим строку
(setvar "osmode" osm) , которая возвращает привязки.
См. Рис. 18.
Чтобы пользователь мог за один раз отменить все построение тройника, а не делать это пошагово, добавляем следующие строки:
(vla-startundomark active_document) - начало группы для отмены. (vla-endundomark active_document) - окончание группы для отмены.
См. Рис. 19.
Для того, чтобы преобразовать нашу программу в пользовательскую функцию defun.
В начале программы добавим строку, в которой придумаем имя функции (3d_tro) и перечислим все временные переменные:
(defun c:3d_tro (/ R1 L1 bp X1 Y1 Z1 Y2 p2 R2 L2 L21 Z12 osm vla_cil vla_otv cil otv) <наша программа> ) ; end_defun
В конце программы добавим закрывающую скобку.
Окончательный вариант программы см. Рис. 20.
Теперь чтобы загрузить нашу программу нажимаем на кнопку «Загрузить активное окно редактора».
Чтобы запустить нашу новую команду (3d_tro) :
Перейдите в AutoCAD. В командной строке наберите 3d_tro и нажмите клавишу <Enter>.
На запрос: «Укажите базовую точку :». Укажите любую точку в рабочем окне AutoCAD. Программа построит 3D тройник.
Если к этой программе, дополнительно, создать диалоговое окно, в котором будут задаваться радиус (или диаметр) и длина основного цилиндра, радиус и длина ответвления, то программа будет, за считанные секунды, создавать 3D тройники любых диаметров.
Как создать диалоговое окно смотрите в уроке: «Диалоговое окно».
Как управлять диалоговым окном из LISP программы смотрите в уроке: «Пример программы LISP с диалоговым окном»
Вы можете бесплатно скачать LISP программу создания 3D тройника:
Скачать программу 3d_tro.lsp (Размер файла: 927 bytes)
Пример LISP программы — Поворот 3D объекта.
Быстрое создание 3d объекта при 3D моделирование в AutoCAD это только полдела. Хотелось бы еще получить инструмент, позволяющий легко ориентировать 3d объект в пространстве. Давайте напишем программу, которая будет поворачивать, наш объект вокруг оси Y на 90 градусов.
Я бы хотел, чтобы программа работала следующим образом: выделяем 3d объект, запускаем программу вращения и 3d объект поворачивается.
И так приступим:
Добавим начальные функции позволяющие работать с расширением языка AutoLISP:
(vl-load-com) (setq acad_object (vlax-get-acad-object)) (setq active_document (vlax-get-activedocument acad_object)) (setq model_space (vlax-get-modelspace active_document))
Чтобы, программа определила, какой объект выделен в AutoCAD, добавим функцию ssget:
(ssget) – создает набор из заранее выделенных объектов.
Сохраним этот набор в переменной set_obj:
(setq set_obj (ssget))
Чтобы прочитать имя первого элемента в наборе, используем функцию ssname
(ssname set_obj 0), где
set_obj – наш набор; 0 – первый элемент набора (счет элементов начинается с нуля).
Сохраним имя нашего элемента в переменной name_obj
(setq name_obj (ssname set_obj 0))
Преобразуем наш выделенный 3D объект (обычный примитив) в vla-объект
(vlax-ename->vla-object name_obj)
Сохраним имя vla-объект в переменной vla_obj
(setq vla_obj (vlax-ename->vla-object name_obj))
См. Рис. 21.
Ось вокруг, которой мы будем вращать наш 3D тройник должна соответствовать двум условиям:
1) Она должна проходить через центр тройника – точка пересечения осей цилиндров из которых построен тройник.
2) Она должна быть параллельна оси Y.
Как нам определить центр тройника? Давайте поищем его в свойствах vla-объекта (даже если его там нет, там должны быть данные которые помогут его определить).
Для того, чтобы посмотреть свойства vla-объект используем функцию vlax-dump-object
(vlax-dump-object vla_obj)
Перейдите в AutoCAD. Выделите тройник. См. Рис. 22
Вернитесь в редактор Visual LISP. Откройте окно «Консоль Visual LISP», щелкнув по соответствующей кнопке. Выделите весь текст программы и нажмите на кнопку «Загрузить выделенный фрагмент». См. Рис. 23.
В консоле Visual LISP появится дамп vla-объекта – полная распечатка свойств. Просматриваем его внимательно и находим, что координаты нужной нам точки здесь уже есть – это свойства Centroid. См. Рис. 24.
Нам остается лишь извлечь значение этого свойства из объекта. Для этого используем следующую строку:
(vla-get-Centroid vla_obj)
Добавляем эту строку, затем выделяем ее и нажмите на кнопку «Загрузить выделенный фрагмент» (строку (vlax-dump-object vla_obj) можно теперь удалить). См. Рис. 25.
В консоле Visual LISP видим, что данная строка возвращаем значение типа variant. Добавляем функцию vlax-variant-value, которая читает значение данных типа variant:
(vlax-variant-value(vla-get-Centroid vla_obj))
Выделите строку и нажмите на кнопку «Загрузить выделенный фрагмент». См. Рис. 26.
В консоле Visual LISP видим, что данная строка возвращаем значение типа safearray (безопасный массив). Добавляем функцию vlax-safearray->list, которая преобразует безопасный массив в список:
(vlax-safearray->list(vlax-variant-value(vla-get-Centroid vla_obj)))
Выделите строку и нажмите на кнопку «Загрузить выделенный фрагмент». См. Рис. 27.
В консоле Visual LISP видим, что данная строка возвращаем нам координаты нужной нам точки.
Сохраним их в переменной p_obj:
(setq p_obj (vlax-safearray->list(vlax-variant-value(vla-get-Centroid vla_obj))))
Дальше действуем так же как при повороте цилиндра в предыдущей программе:
Разложим координаты полученной точки:
(setq X1 (nth 0 p_obj)) – координата X центральной точки тройника. (setq Y1 (nth 1 p_obj)) – координата Y центральной точки тройника. (setq Z1 (nth 2 p_obj)) – координата Z центральной точки тройника.
Координаты второй точки должны отличаться центральной точки тройника, только координатой Y.
Изменим координату Y:
(setq Y2 (+ Y1 100))
И соберем координаты второй точки в новый список.
(list X1 Y2 Z1)
И применим функцию вращения vla-Rotate3D:
(vla-Rotate3D vla_obj (vlax-3D-point (list X1 Y1 Z1)) (vlax-3D-point (list X1 Y2 Z1)) (/ Pi 2)), где
vla_obj - вращаемый vla_объект; (list X1 Y1 Z1) и (list X1 Y2 Z1) – координаты точкек прямой вокруг которой происходит вращение; (/ Pi 2) - величина угла поворота в радианах
Добавьте эти строки, выделите их, и нажмите на кнопку «Загрузить выделенный фрагмент».
Затем перейдите в AutoCAD. См. Рис. 28.
Тройник повернется. См. Рис. 29.
Преобразовать нашу программу в пользовательскую функцию defun.
В начале программы добавим строку, в которой придумаем имя новой команды (roY) и перечислим все временные переменные:
(defun c:roY (/ set_obj name_obj vla_obj p_obj X1 Y1 Z1 Y2) <наша программа> ) ; end_defun
В конце программы добавим закрывающую скобку.
См. Рис. 30.
Давайте проверим как работает новая команда roY:
Нажмите на кнопку “Загрузить активное окно редактора».
Перейдите в AutoCAD.
Выделите тройник.
Введите в командной строке roY и нажмите <Enter>.
Тройник повернется. См. Рис. 31.
С самого начала я предполагал, что назначу этой команде Горячую клавишу. Как это сделать смотрите в уроке: Горячие клавиши Автокад.
Я назначил, этой команде сочетание клавиш <Shift+A>. Теперь выделяю тройник, нажимаю сочетание клавиш <Shift+A> и тройник поворачивается.
Неудобство заключается в том, что перед каждым поворотом мне нужно выделять тройник.
Чтобы каждый раз не выделять тройник добавим в программу строку:
(sssetfirst nil set_obj)
Которая будет делать это за нас.
Окончательный вариант программы см. Рис. 32.
Эта программа будет вращать не только 3D тройник, но и любой другой 3D объект.
Без особого труда, теперь можно написать программы для вращения 3D объекта вокруг осей X и Z.
Назначить для них горячие клавиши <Shift+X> и <Shift+Z>, и ориентация 3D объект в пространстве станет удобной и быстрой.
Смотрите видео к этому уроку:
На этом наш урок окончен. Надеюсь, что эта статья оказалось кому-то полезной, и 3D моделирование в AutoCAD, стало для Вас более быстрым и комфортным.
Вы можете бесплатно скачать LISP программу создания 3D тройника и программу вращение 3D объекта.
Скачать программу 3d_tro.lsp (Размер файла: 927 bytes)Если у Вас появились вопросы, задавайте их в комментариях.
Я с удовольствием отвечу.
Также пишите в комментариях или мне на почту:
Была ли для Вас полезной информация, данная в этом уроке?
На какие вопросы программирования, Вы хотели бы, увидит ответы в следующих уроках?
Ваши мнения очень важны для меня.
Если вы хотите получать новости с моего сайта. Оформляйте подписку.
До новых встреч.
«Автор: Михаил Орлов»
Спасибо за урок! У меня небольшой вопрос не по теме, попробовал написать простенькую программку для простановки отверстий на планах. Вопрос следующий: как округлить полученную величину s1 до десятков, скажем 415 до 420? Спасибо за внимание.
Округление s1 до десятков:
Добрый день, подскажите пожалуйста, возможно ли объединить функции двух команд. А именно хочу получить отметку взяв ее просто щелчком мыши с значения однострочного текста или вводя в командную строку значения вручную:
И еще вопрос, если первый вариант не возможен, как создать выпадающий список при нажатии на правую клавишу мыши> выбор по двум сценариям 1 — ввод вручную, 2 — клик по примитиву _text.
Спасибо за подсказку, этот фрагмент использовал в программке расчета отметки линейной интерполяцией. Еще вопрос, возможно ли задать initget значение выбора по умолчанию? Не получается организовать цикл на проверку значения выбранной отметки на nil, чтобы избежать сообщения «ошибка: неверный тип аргумента: lentityp nil» при «промахе» по тексту. Если использовать функцию (while как добиться заново выполнять код на выбор текста. Код программки пока такой:
Спасибо за внимание!
initget — задает допустимые варианты ввода.
Если есть варианты выбора мы может, только пометить один из них.
Но выбор все равно делает пользователь.
Если нужно задать один параметр, то значение по умолчанию можно добавить:
Цикл на проверку nil и на проверку выбора не того примитива (если выбран не текст):
Спасибо!
Очень интересно было бы в будущем увидеть урок на тему создания простейшей программы по отрисовки 2d воздуховодов или трубопроводов, на примере пары типоразмеров, используя стандартные объекты автокада: мультилинию для тела воздуховода или трубы, блоки — для фасонных деталей сети.
Посмотрите эту статью: http://acad-prog.ru/multiliniya-v-avtokade/