JavaScript — эффективный инструмент конструктора-технолога для расширения функциональности САПР БАЗИС (часть 2)
В предыдущей статье, посвященной инструментальным средствам расширения функциональности САПР корпусной мебели БАЗИС [1], рассказывалось о том, как организовать пользовательский интерфейс встроенных скриптовых программ. Для получения полного представления о методике их разработки рассмотрим вторую часть задачи построения параметрической модели типового изделия (тумбочки) — моделирование панелей и фурнитуры. Напомним, что речь идет о функции Make(), цель работы которой заключается в формировании полного набора элементов, образующих тумбочку, в области скрипта.
Начало работы
Функция построения тумбочки Make() вызывается в трех случаях:
- при запуске скрипта для построения модели с параметрами, заданными по умолчанию или считанными из файла настроек;
- при любом изменении параметров в окне свойств;
- по окончании работы скрипта.
Описание функции в языке JavaScript выглядит следующим образом:
functionMake() {
<Тело функции>
}
Перед началом построения необходимо выполнить несколько вспомогательных операций:
- очистить область скрипта, поскольку в ней могут находиться ранее построенные объекты;
- определить толщину материала задней стенки. В моделируемом варианте тумбочки задняя стенка устанавливается в пазы, формируемые на габаритных панелях. Материал, из которого она изготавливается (MatBackWall), задается пользователем в окне свойств. Знание толщины этого материала необходимо для расчета ширины пазов. Определить ее значение можно за два действия: назначить материал задней стенки текущим материалом (метод SetActive()), то есть материалом построения всех последующих панелей, и сохранить соответствующее свойство в некоторой переменной (ThickBackWall);
- установить новый текущий материал — материал, из которого собственно и изготавливается тумбочка (MatKorp). Он также задается пользователем в окне свойств;
- сохранить толщину текущего материала в некоторой переменной (Thick);
Команды, реализующие эти операции, выглядят следующим образом:
DeleteNewObjects();
MatBackWall.SetActive();
ThickBackWall = ActiveMaterial.Thickness;
MatKorp.SetActive();
Thick = ActiveMaterial.Thickness;
Построение корпуса
Построение тумбочки (как и любой другой корпусной мебели) представляет собой процесс размещения панелей в пространстве (глобальной системе координат) с их позиционированием друг относительно друга. Традиционно мебельщики разделяют панели по их ориентации в пространстве на горизонтальные, вертикальные и фронтальные панели. На рис. 1 иллюстрируется это разделение, а также показывается положение центра локальной системы координат для каждого типа панелей и направления осей координат.
При установке панель считается прямоугольной (с геометрической точки зрения — это параллелепипед), поэтому для ее определения в глобальной системе координат необходимо указать:
- две координаты, задающие положение вершины прямоугольника, соответствующей началу локальной системы координат (точка привязки);
- две координаты, задающие положение противоположенной диагональной вершины;
- координату, определяющую положение панели в пространстве.
Рис. 1. Глобальная и локальные системы координат панелей
В дальнейшем контур панели можно редактировать произвольным образом. Толщина панели определяется толщиной текущего материала. С учетом обозначений, приведенных на рис. 1, функции создания панелей имеют следующие параметры:
- AddHorizPanel(x1, z1, x2, z2, y) — горизонтальная панель;
- AddVertPanel(z1, y1, z2, y2, x) — вертикальная панель;
- AddFrontPanel(x1, y1, x2, y2, z) — фронтальная панель.
Для определения крышки тумбочки (горизонтальная панель) необходимо выполнить вызов функции AddHorizPanel:
Cover= AddHorizPanel(0, 0, Dl.Value, Gl.Value, H.Value Thick);
Смысл параметров вызова таков:
- первая пара параметров говорит о том, что начало локальной системы координат панели совпадает с началом глобальной системы координат;
- размер панели по оси X равен значению ширины тумбочки Dl.Value (см. предыдущую статью);
- размер панели по оси Z равен значению глубины тумбочки Gl.Value;
- поскольку точкой привязки горизонтальной панели является ее «нижняя» вершина и при этом сама панель не должна «выступать» за габарит тумбочки по высоте, для задания ее координаты по оси Y необходимо из значения высоты тумбочки (H.Value) вычесть толщину панели (Thick), определенную выше.
Для идентификации построенной панели в конструкторскотехнологических документах зададим ее наименование:
Cover.Name = ‘Крышка’;
Следующая операция — облицовка кромок панели материалами, заданными в окне свойств. Предположим, что задняя кромка панели облицовывается материалом «невидимая кромка» (KrNotVidimKorp), а остальные — материалом «видимая кромка» (KrVidimKorp). Оба эти материала задаются в окне свойств. Для облицовки используется метод панели AddButt(material, elem). Первый параметр определяет облицовочный материал, а второй — номер элемента контура, на который наносится облицовка. Элементы контура упорядочены против часовой стрелки и нумеруются с нуля. Нулевым элементом контура панели считается отрезок, начинающийся в точке начала локальной системы координат и направленный вдоль той оси, координата по которой указывается первым параметром в функции создания панели. Для горизонтальной панели нулевым элементом является задняя кромка. Таким образом, для облицовки всех кромок необходимо выполнить четыре вызова метода AddButt:
Cover.AddButt(KrNotVidimKorp, 0);
Cover.AddButt(KrVidimKorp, 1);
Cover.AddButt(KrVidimKorp, 2);
Cover.AddButt(KrVidimKorp, 3);
Конструкция тумбочки предполагает установку задней стенки в паз, поэтому сразу добавим соответствующий объект в создаваемую панель, указав его обозначение:
Cut = Cover.AddCut(‘Паз для задней стенки’);
Рис. 2. Параметры построения паза
Паз определяется двумя параметрами: траекторией и контуром поперечного сечения (рис. 2). Примем следующие параметры паза:
- глубина — 10 мм;
- ширина — на 0,5 мм больше толщины задней стенки;
- отступ от задней кромки крышки — 10 мм.
Траектория паза представляет собой отрезок, параллельный задней кромке крышки, смещенный от нее «внутрь» на 10 мм. Координаты траектории задаются в системе координат панели, поэтому величина смещения будет отрицательной (см. рис. 1). Контур паза — прямоугольник. С учетом этого для построения паза следует выполнить команды:
Traj = Cut.Trajectory;
Traj.AddLine(0, 10, Dl.Value, 10);
ContPaz = Cut.Contour;
ContPaz.AddRectangle(0, 0, ThickBackWall 0.5, 10);
Построение крышки на этом завершается. Для ее визуализации необходимо обратиться к методу Build, который реализует построение панели в соответствии с заданными параметрами:
Cover.Build();
Левая боковина стенки тумбочки (вертикальная панель) строится аналогично крышке, но с небольшими отличиями.
LeftWall = AddVertPanel(0, 0, Gl.Value, H.Value Thick, 0);
LeftWall.Name = ‘Боковина левая’;
В заднем нижнем углу панели строится фаска под плинтус. Геометрически она представляет собой отрезок с углом наклона 45°, начальная и конечная точки которого расположены на указанном расстоянии от угла (Fas.Value). Для построения фаски используется метод Facet объекта Contour, параметрами которого являются координаты точки, ближайшей к фаске, и данное расстояние:
LeftWall.Contour.Facet(0, 0, Fas.Value);
Еще одно отличие от построения крышки заключается в облицовке кромок: «верхнюю» кромку (второй элемент контура) облицовывать не надо, поскольку она закрывается крышкой:
LeftWall.AddButt(KrNotVidimKorp, 0);
LeftWall.AddButt(KrVidimKorp, 1);
LeftWall.AddButt(KrNotVidimKorp, 3);
LeftWall.AddButt(KrNotVidimKorp, 4);
Для построения паза служит последовательность команд, аналогичная той, что использовалась в случае с крышкой:
Cut = LeftWall.AddCut(‘ Паз для задней стенки’);
Traj = Cut.Trajectory;
Traj.AddLine(10, 0, 10, H.Value Thick);
ContPaz = Cut.Contour;
ContPaz.AddRectangle(0, 0, ThickBackWall 0.5, 10);
LeftWall.Build();
Правая боковина тумбочки зеркально симметрична левой боковине, поэтому для ее построения отобразим левую боковину симметрично относительно вертикальной плоскости, проходящей параллельно ей через середину тумбочки:
RightWall = AddSymmetry(LeftWall, NewVector(Dl.Value / 2, 0, 0), AxisX);
Параметры функции симметричного отображения следующие:
- отображаемый объект — ранее построенная левая боковина;
- координаты точки, через которую проходит плоскость симметрии, в глобальной системе координат (функция NewVector из трех действительных чисел (координат) создает объект «точка»);
- вектор нормали к плоскости симметрии, который в данном случае совпадает с осью Х глобальной системы координат. Он определяет ориентацию плоскости в пространстве.
При создании новой панели с помощью симметричного отражения в нее копируются все свойства исходной панели. Единственное свойство, которое надо изменить в правой боковине, — название панели:
RightWall.Name = ‘Боковина правая’;
После создания панели с помощью симметричного отображения метод построения Build вызывать необязательно, поскольку изменение имени никак не влияет на изображение панели.
Дно (горизонтальная панель) и цокольная планка (фронтальная панель) строятся аналогичным образом. Отличия в том, что у дна не облицовываются боковые кромки (элементы 1 и 3), а у цокольной планки облицовывается только нижняя кромка (элемент 0).
Цокольная планка размещается между боковинами (то есть ее длина равна ширине тумбочки, уменьшенной на две толщины текущего материала) с заглублением на 20 мм. Последнее означает, что ее координата по оси Z равна глубине тумбочки, уменьшенной на 20 мм и толщину текущего материала (см. рис. 1). Соответствующий фрагмент скрипта имеет вид (параметр Hd.Value — отступ дна от поверхности пола):
Bottom = AddHorizPanel(Thick, 0, Dl.Value Thick, Gl.Value, Hd.Value);
Bottom.Name = ‘Дно’;
Bottom.AddButt(KrNotVidimKorp, 0);
Bottom.AddButt(KrVidimKorp, 2)
Cut = Dno.AddCut(‘ Паз для задней стенки’);
Traj = Cut.Trajectory;
Traj.AddLine(0, 10, Dl.Value Thick, 10);
ContPaz = Cut.Contour;
ContPaz.AddRectangle(0, Thick, ThickBackWall 0.5, Thick 10);
Bottom.Build();
Socle = AddFrontPanel(Thick, 0, Dl.Value–2*Thick, Hd.Value, Gl.Value 20 Thick);
Socle.Name = ‘Цоколь’;
Socle.AddButt(KrNotVidimKorp, 0);
Socle.Build();
Построение вкладной полки и задней стенки
Полка располагается посередине между дном и крышкой тумбочки «впритык» к задней стенке, с заглублением на 30 мм относительно переднего среза и с боковыми зазорами по 1 мм с каждой стороны (рис. 3). Для ее построения используется функция AddHorizPanel(x1, z1, x2, z2, y). Первые четыре параметра, определяющие контур панели, в соответствии с рис. 3 вычисляются следующим образом:
- координаты точки привязки (левой задней точки) — (Thick + 1, 10 + ThickBackWall);
- координаты точки, определяющей размер прямоугольного контура панели (правой передней точки) — (Dl.Value Thick 1, Gl.Value 30).
Для указания положения полки по оси Y надо найти середину внутреннего пространства тумбочки и совместить с ним середину «толщины» панели. Другими словами, координата полки по вертикали будет расположена ниже середины внутреннего пространства тумбочки на величину 0,5* Thick.
Рис. 3. Параметры построения полки
Для нахождения координаты средней точки из высоты тумбочки (H.Value) вычитается толщина крышки (Thick), отступ дна от пола (Hd. Value) и толщина дна (Thick), после чего берется половина найденного значения:
Hp = (H.Value Thick Hd.Value– Thick)*0.5;
Поскольку с найденной точкой надо совместить середину полки, вычитаем из полученного значения половину толщины материала:
Hp = Hp 0.5 * Thick;
Начало глобальной системы координат находится «на уровне пола», поэтому для определения положения полки по высоте к полученному значению следует прибавить расстояние от «пола» до верхней пласти дна:
Hp = Hp + Hd.Value + Thick;
Таким образом, команда построения полки будет иметь вид:
Polka = AddHorizPanel(Thick + 1, 10 + ThickBackWall, Dl.Value Thick 1, Gl.Value 30, Hp);
Назначение остальных команд очевидно:
Polka.Name = ‘Полка’;
for (var k = 0; k < 4; k++) {
Polka.AddButt(KrDver, k)
}
Polka.Build();
Построение задней стенки отличается от построения остальных панелей двумя нюансами:
устанавливается новый текущий материал MatBackWall;
панель устанавливается с зазором 1 мм по периметру.
MatBackWall.SetActive();
BackWall = AddFrontPanel(Thick 9, Hd.Value + Thick 9, Dl.Value Thick + 9, H.Value Thick + 9, 10);
BackWall.Name = ‘Задняя стенка’;
Построение двери
Дверь является составным элементом (блоком), включающим собственно панель и ручку. Начало блока задается специальной командой BeginBlock с указанием его имени, а конец — командой EndBlock():
Block = BeginBlock(‘Дверь’)
MatDver.SetActive();
ThickDver = ActiveMaterial.Thickness;
Dver = AddFrontPanel(2, Hd.Value + 2, Dl.Value 2, H.Value 2, Gl.Value);
Dver.Name = ‘Дверь’;
for (var k = 0; k < 4; k++) {
Dver.AddButt(KrDver, k)
}
Следующий шаг — установка ручки. Фурнитура в системе БАЗИС представляет собой графическое изображение, создаваемое пользователем и хранящееся в файле [2]. Для определения типа ручки используется функция OpenFurniture, в качестве параметра которой задается имя файла:
Handle = OpenFurniture(‘Ручкаскоба 128.f3d’);
Установка любой фурнитуры (в том числе и ручек) на плоскость производится с помощью метода Mount1(Panel, x, y, z, Angle). Первым параметром определяется панель, далее задаются координаты точки установки в глобальной системе координат и угол поворота относительно ее исходного положения:
Handle.Mount1(Dver, Dl.Value 2 40, H.Value 115, Gl.Value + ThickDver, 0);
На передней пласти двери сделан декоративный вырез — филенка. С точки зрения моделирования она представляет собой паз сложного поперечного сечения, соответствующего профилю фрезы, построенный по некоторой траектории. Отличие от построения паза для задней стенки в основном состоит в том, что контур поперечного сечения не строится явно, а берется из файла и присваивается переменной FileFreza. Естественно, предварительно необходимо убедиться в существовании нужного файла. Команды построения возможных траекторий (в проектируемом скрипте предусматривается четыре их вида) рассматривать не будем. Отметим только, что любая траектория представляет собой последовательность отрезков и дуг, а для организации выбора из четырех вариантов удобно использовать оператор switch. Таким образом, построение филенки будет выглядеть следующим образом:
FileFreza = Freza.Value;
if (system.fileExists(FileFreza)) {
Cut = DverAddCut(‘Филенка’);
Traj = Cut.Trajectory;
switch (TipFilenki.ItemIndex) {
case 0: { <построение траектории 1>; break; }
case 1: { <построение траектории 2>; break; }
case 2: { <построение траектории 3>; break; }
case 3: { <построение траектории 4>; break; }
}
Cut.Contour.Load(FileFreza);
Cut.Contour.Move(0, Dver.Thickness);
}
Dver.Build();
EndBlock();
Контур траектории филенки был построен в плоскости, проходящей через точку привязки фронтальной панели, которая находится на «задней» поверхности двери (см. рис. 1). Его необходимо переместить на «переднюю» поверхность, то есть сдвинуть по оси Z на толщину материала двери — Dver.Thickness.
Для моделирования открытия двери в модуле БАЗИСМебельщик установим тип анимации — левая дверь:
Block.AnimType = AnimationType.DoorLeft;
Расстановка крепежа
Крепеж представляет собой фурнитуру, предназначенную для соединения между собой двух панелей. Для его установки используется метод Mount(Panel1, Panel2, x, y, z), первыми двумя параметрами которого являются соединяемые панели. Из трех координат точно требуется указывать только одну — ту, вдоль которой располагаются элементы крепежа. Две другие координаты лишь обозначают сектор размещения. Например, петли устанавливаются вдоль вертикальной оси, поэтому точные значения присваиваются координате Y, а координаты X и Z определяют сектор, в котором будет расположен крепеж. Полкодержатели устанавливаются вдоль горизонтальной оси Z, координаты по которой и задаются точно; сектор же определяется координатами X и Y.
Тип крепежа указывается пользователем в окне свойств. Он может быть как параметрическим, так и произвольным. Предположим, что устанавливаемые петли являются параметрическим крепежом, а в переменной SY находится точная координата по оси Y одной из них. Тогда для установки петли на модель необходимо выполнить команды:
FPetli = Petli.Value;
FPetli.Mount(LeftWall, Dver, 2 * Thick, SY, 0);
Точки с координатами (x=2*Thick, z=0) однозначно определяют сектор, в котором будет размещена петля — внутреннее пространство тумбочки.
Предположим далее, что полкодержатели относятся к классу произвольного крепежа и их параметры находятся в файле. Для размещения одного из них рассчитана точная координата SZ по оси Z. В этом случае установка полкодержателя выполняется командами:
Polkodergatel = OpenFurniture(‘Полкодержатель.f3d’);
Polkodergatel.Mount(Polka, LeftWall, 2 * Thick, 0, SZ);
Аналогичным образом устанавливаются все элементы крепежа, и создание скрипта для построения тумбочки считается завершенным. После этого команда построения тумбочки, по сути, становится встроенной командой модуля БАЗИСМебельщик и может вызываться с любыми параметрами.
Заключение
Данный цикл статей не ставит своей целью обучение программированию на языке JavaScript. Для этого существуют специальные учебные пособия [3, 4, 5]. Да и сам скрипт можно было бы написать более компактно и изящно. Главная задача публикации — показать, что самостоятельная разработка программ на JavaScript в среде САПР БАЗИС вполне доступна конструкторам и технологам мебельных предприятий. Ведь при внимательном рассмотрении программы оказывается, что она представляет собой последовательность действий, которые необходимо произвести при привычном конструировании мебели в системе БАЗИС. Только они не выполняются в режиме диалога, а записываются по определенным правилам.
Как показал первый опыт использования нового инструментария, специалисты, знакомые с программированием лишь в объеме средней школы, быстро осваивают JavaScript, создавая интересные и полезные приложения, то есть значительно повышают эффективность своей работы.
Литература
- Бунаков П.Ю. JavaScript — эффективный инструмент конструкторатехнолога для расширения функциональности САПР БАЗИС (часть 1) // САПР и графика. 2014. № 2(207). С. 5356.
- Бунаков П.Ю. Моделирование мебельной фурнитуры в системе БАЗИС // САПР и графика. 2013. № 10(203). С. 2225.
- Современный учебник JavaScript [Электронный ресурс] / http://learn.javascript.ru/
- Флэнаган Д. JavaScript. Карманный справочник / Дэвид Флэнаган — М.: Вильямс, 2013. 320 с.
- Херман Д. Сила JavaScript. 68 способов эффективного использования JS / Дэвид Херман — СПб.: Питер, 2013. 288 с.