Функции в OpenSCAD предназначены для вычисления каких-либо значений и всегда возвращают свой результат. Объявление функции имеет вид
function название(список_аргументов) = тело_функции;
При объявлении можно задавать значения аргументов по умолчанию с помощью знака равенства. В вызове функции агрументы могут быть просто перечислены в порядке объявления, либо переданы по имени. Язык программирования поддерживает использование тернарного оператора условие ? действие_1 : действие_2, который может быть использован, в частности, для организации рекурсивных вызовов.
В качестве примера рассмотрим функцию poly(), вычисляющую значение полинома в точке x по схеме Горнера. Коэффициенты полинома заданы в виде вектора. Поскольку, язык не допускает изменение значения переменной, вместо цикла использована рекурсия. Основная работа происходит во вспомогательной функции poly1(), которая сравнивает счётчик с длиной вектора коэффициентов (функция len()) и рекурсивно вычисляет результат. Команда let() позволяет объявить временные переменные в теле функции для упрощения дальнейших вычислений. Результат выводится в консоль функцией echo(), которая отображает значения всех своих аргументов.
Согласно описанию, в OpenSCAD можно создавать лямбда-функции и присваивать их переменным в let(), однако, у меня данный функционал не заработал. Возможно, дело в версии программы.
В отличие от функции, модуль не возвращает значения, а строит объекты или определяет операции над ними. Синтаксис объявления имеет вид
module название(список_аргументов) { тело_модуля }
Тело модуля может включать в себя практически любые инструкции, разрешённые в OpenSCAD, включая объявление вспомогательных функций и модулей. Можно даже строить объекты с помощью рекурсивных вызовов, главное, помнить про ограниченность глубины стека.
Как было сказано выше, модули могут определять не только геометрические объекты, но и операции над ними. Для обращения к потомку используется команда children(), которая допускает использование различных аргументов, например, индекса конкретного потомка. Следующий код приводит к случайному размещению элемента на поле заданного размера. Число потомков определяется параметром $children, индексация начинается с нуля. Функция rands() генерирует вектор случайных чисел заданной длины в указаном диапазоне.
В данном примере используется тип данных range, который определяется как [начало : шаг : конец] и является списком элементов из заданного диапазона. Для обхода потомков использован цикл for.
Текстовый формат представления моделей и операций над ними упрощает повторное использование кода и создание библиотек элементов. Список наиболее функциональных из них можно найти на сайте www.openscad.org. Подключение библиотеки производится ключевыми словами include и use. В первом случае, импортируемый код будет "вставлен" в ваш сценарий, соответственно, если в нём присутствуют какие-то исполняемые действия и вызовы, они будут исполнены. Во втором случае загружаются только объявления функций и модулей.
Допустим, написанный ранее код был сохранён в файл snowman.scad. В следующем примере показано использование импортированного кода. Поскольку операция randomize() может работать с несколькими потомками, в первом случае мы вручную создаём каждого отдельного снеговика (синий цвет). Если объектов много, эффективнее генерировать их в цикле, что и сделано во втором случае.
Комментариев нет:
Отправить комментарий