Скрипты в системе БАЗИС являются эффективным средством для оптимизации проектирования. Они расширяют множество ее команд, позволяя учесть специфичес-кие условия любого предприятия. В статье на конкретных примерах показывается, как разрабатываются скрипты и как они интегрируются в систему БАЗИС.
Как известно, слово «скрипт» в переводе с английского означает «сценарий» — последовательность действий для достижения той или иной цели. Можно сказать, что скрипт является программой, которая выполняется в режиме интерпретации другой программой. В рассматриваемой ситуации некоторая последовательность команд, записанная в файле, при каждом обращении к скрипту «прочитывается» и выполняется модулем БАЗИС-Мебельщик. Результатом, естественно, будут определенные изменения в текущей проектируемой модели или новая модель.
Процесс программирования проектировщикам, конструкторам и технологам, часто кажется сложным, а затраты времени и усилий на изучение языков и технологий программирования не соответствующими будущим результатам. Здесь можно привести четыре аргумента:
- Основы программирования, а именно они и нужны для создания скриптов, в реальности гораздо проще, чем это представляется со стороны. Тем более что в системе БАЗИС используется очень популярный и в то же время простой язык программирования JavaScript.
- При написании скриптов программист в большинстве случаев оперирует понятными объектами и процессами, с помощью которых он моделирует изделия в БАЗИС-Мебельщик, такими как панель, материал, фурнитура, облицовывание кромок, расстановка крепежа и т.д. Разница лишь в том, что он работает с ними не в диалоге с системой, а описывает свою работу с помощью команд языка.
- Время, единожды потраченное на изучение основ программирования, и время, затрачиваемое на написание скриптов, в будущем сэкономит не только часы и минуты, но и нервы — ведь отлаженный скрипт не допускает ошибок и при каждом запуске быстро выдает правильный и точный результат.
- Наконец, программирование — это очень увлекательно. Начиная новое дело, человек всегда испытывает страх или неуверенность. Однако через некоторое время всё становится понятным и знакомым, а скрипты превращаются в еще один мощный и гибкий инструмент, облегчающий работу. На мебельных форумах можно найти сотни самых разнообразных скриптов, написанных мебельщиками, что подтверждает всё вышесказанное.
В данной статье не будет сложной теории алгоритмизации или подробного описания языка программирования JavaScript. У нее другая цель — показать на несложных примерах, что создание скриптов в системе БАЗИС по силам любому мебельщику. С этой же целью мы не будем использовать кроссплатформенный редактор исходного кода программ Visual Studio Code, в котором можно писать и отлаживать скрипты для системы БАЗИС, а ограничимся более простым встроенным редактором кода (рис. 1).
Рис. 1. Встроенный редактор кода
Установка ручек
Начнем с самого простого скрипта, который позволит устанавливать ручки на рамочные фасады по центру указанной рамки. Имеется шкаф с антресолью (рис. 2) и четырьмя дверями, на которые надо установить ручки.
Рис. 2. Модель шкафа (разработана конструктором мебели Екатериной Румянцевой, Telegram: @vash_konstruktor)
Предварительно создадим модель ручки и сохраним ее в виде фрагмента с именем Ручка.fr3d. Для примера выберем ручку-скобу (рис. 3). В качестве точки привязки укажем ее середину. Поскольку при каждом вызове скрипта количество устанавливаемых ручек может быть различным, для завершения процесса создадим специальную кнопку Закончить.
Рис. 3. Фрагмент ручки
Приступаем к написанию скрипта. Первый шаг: создаем объект Furn, в который помещаем фрагмент ручки:
Furn = OpenFurniture('Ручка.fr3d');
Далее создаем объект Кнопка (Button), указывая, что при ее нажатии выполняемое действие (Action), то есть установка ручек, должно завершиться:
BtnStop = NewButtonInput('Закончить');
BtnStop.OnChange = function(){
Action.Finish();
}
Для установки произвольного количества ручек организуем «бесконечный» цикл, который будет выполняться до нажатия кнопки Закончить:
while (true) {
}
Внутри этого цикла записываем такую последовательность команд для установки очередной ручки:
Выбираем панель для установки и создаем соответствующий объект:
Panel = GetPanel('Укажите панель');
Определяем габаритные точки модели ручки:
min = Panel.Contour.Min;
max = Panel.Contour.Max;
Создаем трехмерную точку, координаты х и y которой соответствуют середине контура панели. Панель, на которую будет устанавливаться ручка, является фронтальной панелью, и ее точка привязки — это левая задняя габаритная точка. Ручка же должна находиться спереди, поэтом координата z равна толщине панели:
pt = {
x: (min.x + max.x) / 2,
y: (min.y + max.y) / 2,
z: Panel.Thickness
}
Локальные координаты полученной точки на панели переводим в глобальные координаты:
pt = Panel.ToGlobal(pt);
Устанавливаем ручку в нужную точку на панели (последний параметр — это угол поворота в градусах):
Furn.Mount1(Panel, pt.x, pt.y, pt.z, 0);
На модели шкафа четыре двери — соответственно, указываем четыре панели рамочной двери и получаем результат (рис. 4). Отметим, что данный скрипт не просто устанавливает ручку, но и формирует отверстия для ее крепления на панели (рис. 5).
Рис. 4. Установка ручек
Установка полок
Рассмотрим более «сложный» скрипт, который устанавливает съемные полки в нишу, образованную четырьмя панелями. Зададим следующие исходные данные:
- количество полок — ShelfCount (по умолчанию — 5);
- боковой зазор — OffsetSide, то есть расстояние от боковых панелей ниши до полок (по умолчанию — 2 мм);
- заглубление спереди — OffsetFront (расстояние от переднего среза ниши до полок, по умолчанию — 5 мм);
- отступ для полкодержателей — OffsetShelf (по умолчанию — 30 мм). Полки будут устанавливаться на два полкодержателя. Расстояние от задней кромки полки до первого полкодержателя равно значению отступа. Второй полкодержатель устанавливается так, чтобы расстояние между ними было кратно 32 мм, и при этом расстояние от него до передней кромки полки не должно превышать значения отступа.
Рис. 5. Чертеж панели с отверстиями
Вначале вводим эти четыре значения:
ShelfCount = NewNumberInput('Количество полок');
ShelfCount.Value = 5;
OffsetSide = NewNumberInput('Боковой зазор');
OffsetSide.Value = 2;
OffsetFront = NewNumberInput('Заглубление спереди');
OffsetFront.Value = 5;
OffsetShelf = NewNumberInput('Отступ для полкодержателей');
OffsetShelf.Value = 30;
Далее переходим на вид спереди и указываем четыре панели, образующие нишу:
SetCamera(p3dFront);
Left = GetPanel('Укажите левую панель');
Right = GetPanel('Укажите правую панель');
Top = GetPanel('Укажите верхнюю панель');
Bottom = GetPanel('Укажите нижнюю панель');
Полки будут строиться из текущего материала, который определяется переменной ActiveMaterial. Создадим переменную для хранения его толщины:
Thick = ActiveMaterial.Thickness;
Как и в предыдущем примере, определим крепежную фурнитуру:
Shelf = OpenFurniture('Полкодержатель.f3d');
Приступаем к расчету параметров размещения полок. Для этого прежде всего надо знать направления осей координат: ось Х направлена влево, ось Y — вверх и ось Z — вперед. Таким образом, минимальная координата Y ниши (переменная PosY) определяется максимальным габаритным размером нижней панели:
PosY = Bottom.GabMax.y;
Соответственно, максимальная координата Y ниши — это минимальный габаритный размер верхней панели. Исходя из этого рассчитаем расстояние между полками:
YInc = (Top.GabMin.y – PosY – ShelfCount.Value * Thick) / (ShelfCount.Value + 1);
Глубина ниши рассчитывается по координате Z. Будем считать, что она определяется боковыми панелями ниши и вычисляется как расстояние между минимальным из максимальных координат Z этих панелей (ZMax) и максимальным из минимальных координат (ZMin). Рассчитаем эти значения, причем при вычислении ZMax сразу учтем заглубление полок спереди:
if (Left.GabMax.z > Right.GabMax.z)
{
ZMax = Right.Left.GabMax.z – OffsetFront.Value
}
else
{
ZMax = Left.GabMax.z – OffsetFront.Value
};
if (Left.GabMin.z > Right.GabMin.z)
{
ZMin = Left.GabMin.z
}
else
{
ZMin = Right.GabMin.z
};
Далее определяем расположение полкодержателей по оси Z, то есть по горизонтали вдоль полки. Для первого из них (ZFirst) это очевидно: к минимальной координате Z полки надо просто прибавить значение отступа. Со вторым (ZLast) несколько сложнее. Вначале определим, сколько отрезков по 32 мм можно разместить между ними. Для этого из глубины панели
(ZMax – ZMin) вычтем удвоенное значение отступа, разделим результат на 32 и округлим его с недостатком:
N = Math.floor((ZMax – ZMin – 2 * OffsetShelf.Value) / 32);
Теперь расстояние между полкодержателями рассчитывается просто: к значению ZFirst прибавляем константу N * 32.
Осталось организовать цикл установки нужного количества полок. Для получения координаты Y нижней полки надо к минимальной координате ниши добавить рассчитанное расстояние между полками, а затем нарастающим итогом добавлять его для каждой последующей полки:
for (var k = 0; k < ShelfCount.Value; k++) {
PosY += YInc;
Panel = AddHorizPanel(Left.GabMax.x + OffsetSide.Value, ZMin,
Right.GabMin.x – OffsetSide.Value, ZMax, PosY);
ZFirst = Panel.GabMin.z + OffsetShelf.Value;
ZLast = ZFirst + N * 32;
Shelf.Mount(Panel, Left, Left.GabMax.x, PosY, ZFirst);
Shelf.Mount(Panel, Right, Right.GabMin.x, PosY, ZFirst);
Shelf.Mount(Panel, Left, Left.GabMax.x, PosY, ZLast);
Shelf.Mount(Panel, Right, Right.GabMin.x, PosY, ZLast);
PosY += Thick;
}
Для установки горизонтальной панели (функция AddHorizPanel) необходимо указать минимальные и максимальные координаты по оси X с учетом боковых зазоров (соответственно, Left.GabMax.x + OffsetSide.Value и Right.GabMin.x – OffsetSide.Value) и по Z (ZMin и ZMax), а также высоту расположения нижней пласти (PosY). Далее размещаем два полкодержателя сзади и два — спереди, после чего увеличиваем координату Y на толщину установленной полки.
При запуске скрипта появляется панель ввода параметров с их значениями по умолчанию и первый из запросов — ‘Укажите левую панель’ (рис. 6). Если это необходимо, вводим значения параметров и указываем панели, образующие нишу. После указания последней панели получаем результат (рис. 7). Рядом с изображением показано, что полки размещены равномерно с соблюдением бокового зазора.
Рис. 6. Панель ввода параметров
Рис. 7. Результат работы скрипта
Фрезерование панели
Следующий скрипт предназначен для декоративного фрезерования пласти фронтальной панели (как правило, фасада) по определенной траектории. Пусть это будет фигура в виде прямоугольника, у которого верхняя сторона заменена полуокружностью.
Рис. 8. Профиль фрезы
Прежде всего необходимо построить профиль фрезы и сохранить его в качестве двумерного фрагмента (рис. 8). В качестве входного параметра зададим отступ от края панели. Создаем два соответствующих объекта и запрашиваем фрезеруемую панель:
Profile = 'Фреза.frw';
Offset = NewNumberInput('Отступ от края панели');
Offset.Value = 50;
Panel = GetPanel('Укажите панель');
Радиус полуокружности равен половине ширины панели, уменьшенной на два отступа от края:
r = (Panel.Contour.Max.x - Panel.Contour.Min.x - 2 * Offset.Value) / 2;
Для построения траектории определим четыре точки:
левая нижняя точка траектории:
p0 = {
x: Offset.Value,
y: Offset.Value
}
первая крайняя точка полуокружности:
pd1 = {
x: Offset.Value,
y: Panel.Contour.Max.y - Offset.Value - r
}
вторая крайняя точка полуокружности:
pd2 = {
x: Panel.Contour.Max.x - Offset.Value,
y: pd1.y
}
центр полуокружности:
pdc = {
x: pd1.x + r,
y: pd1.y
}
По терминологии системы БАЗИС любой вырез на панели называется пазом — это объект Cut. Добавим его на панель:
Cut = Panel.AddCut('Фрезеровка');
Траектория (объект Trajectory) — это последовательность отрезков и дуг, по которой должна перемещаться середина фрезы. Для ее построения последовательно добавляем к соответствующему объекту отрезки (AddLine) и полуокружность (AddArc), начиная с левого нижнего угла — точки р0:
Cut.Trajectory.AddLine(p0.x, p0.y, pd1.x, pd2.y);
Cut.Trajectory.AddArc(pd1, pd2, pdc, false)
Cut.Trajectory.AddLine(pd2.x, pd2.y, pd2.x, p0.y);
Cut.Trajectory.AddLine(pd2.x, p0.y, p0.x, p0.y);
Загружаем профиль фрезы:
Cut.Contour.Load(Profile);
У фронтальной панели начальная точка находится в левой нижней задней вершине, поэтому контур фрезерования необходимо сместить на переднюю пласть, то есть, не сдвигая по оси X, переместить по оси Z на толщину панели:
Cut.Contour.Move(0, Panel.Thickness);
Перестраиваем панель и получаем фрезерованный фасад (рис. 9):
Panel.Build();
Если создать чертеж фасада, то на нем будет изображен построенный вырез и показано его сечение A–A (рис. 10).
Рис. 9. Фасады с фрезеровкой
Рис. 10. Чертеж фасада
Создание новой команды
При реальной работе из-за большого количества скриптов поиск нужного из них может занимать много
времени. Для быстрого доступа к часто используемым скриптам целесообразно назначить горячие клавиши. В меню Параметры выбираем пункт Горячие клавиши, а в нем — пункт Пользовательские скрипты. Находим нужный скрипт и в специальном окне назначаем горячую клавишу или сочетание клавиш (рис. 11).
Рис. 11. Назначение горячих клавиш
Рис. 12. Активация панели скриптов
Второй вариант ускорения доступа к скриптам — создание кнопки для новой команды. Щелчком правой кнопкой мыши в любом свободном месте области расположения команд вызываем выпадающее меню и активируем в нем панель скриптов (рис. 12). После этого переходим в настройки параметров, где выбираем пункт Панель скриптов (рис. 13). Далее для каждого скрипта назначаем иконку и всплывающую подсказку. Новая команда готова к работе (рис. 14).
Рис. 13. Настройки кнопок для скриптов
Рис. 14. Команда фрезерования фасадов
Заключение
Один из пользователей системы БАЗИС, который ранее не сталкивался с программированием, после изучения скриптов сказал: «Программирование — довольно элементарная вещь, стоит только вникнуть. А насколько же оно увлекательно!..» С ним трудно не согласиться, можно только добавить, что перевод трудоемких и часто встречающихся операций проектирования на скрипты дает возможность увеличить удельный вес творческой работы конструктора.