В данном практическом уроке мы научимся создавать прямой переходник в OpenSCAD c квадратного сечения на круглое.
OpenSCAD позволяет создавать 3D модели с помощью параметрического программирования, это значит, что любую модель в оригинале можно настроить изменив определенные параметры модели.
Мы рассмотрим каждый шаг процесса создания 3D модели переходника, начиная от создания основных форм до окончательной детализации и экспорта готового файла. Будут рассмотрены основные инструменты и функции OpenSCAD, которые позволят создать точную и функциональную модель. Помимо этого, мы также рассмотрим некоторые советы и хитрости, которые помогут упростить процесс моделирования и повысить эффективность работы.
Постановка задачи
Создание любой 3D модели должно начинаться с постановки задачи и формирования технического задания.
В данном примере нам необходимо создать параметрическую модель переходника между двумя трубками: круглого сечения 10мм и квадратного сечения размерами 10мм на 10мм. Модель должна быть легко масштабируема и при необходимости иметь возможность подключаться к разным по диаметру трубкам, минимальная длина соединительной части – 10мм.
Основные инструменты и функции OpenSCAD для создания 3D моделей
В этом подразделе мы рассмотрим основные инструменты и функции OpenSCAD, которые необходимы для создания 3D модели переходника с квадратного сечения на круглое.
1. Определение размеров и параметров модели:
Прежде чем начать создание модели, нужно определить размеры и параметры переходника. Это может включать длину, ширину, высоту, радиус и т.д. В OpenSCAD размеры могут быть заданы явно или через переменные для удобства изменения в будущем.
2. Создание геометрических примитивов:
OpenSCAD предоставляет набор простых геометрических примитивов для создания форм объекта. – Например, для создания куба можно использовать функцию cube([x,y,z]), где x, y и z – размеры сторон куба. А для цилиндра cylinder(height, d, center =true), где H- высота, d-диаметр, center – переменная, отвечающая за центрирование модели ( помещения центра модели в начальную точку координат).
3. Операции над геометрическими примитивами:
После создания примитивов можно выполнять различные операции для модификации и комбинирования их. Например, difference() может быть использована для вычитания геометрических объектов соответственно.
4. Трансформации: – OpenSCAD предоставляет возможность трансформировать созданные объекты с помощью различных операций. Для этого используются команды-модификаторы. В данной ситуации нам понадобится перемещение translate([x,y,z]). Трансформации могут быть применены к отдельным примитивам или ко всей модели целиком.
5. Создание пользовательских функций:
Для более сложных повторяющихся операций можно создавать пользовательские функции. Функции позволяют разделить код на более мелкие блоки и повторно использовать его в разных частях модели. Это особенно полезно, когда определенные операции требуется выполнить несколько раз.
Этапы проектирования
1. Задание переменных
Зададим параметры модели через переменные.
// SCAD скрипт для создания переходника из квадратного сечения в круглое. // Автор: 3d4p.ru //Ширина стенки переходника, умноженная на 2. WallWidth = 2; //Высота концевых участков переходника ModuleHeight =10; //Внутренний диаметр переходника // круглая часть CircleInnerD = 10; //квадратная часть размеры прямоугольника SquareInnerD1 =10; SquareInnerD2 =10;
Создание пользовательских модулей
В OpenSCAD функции и модули представляют два разных подхода к созданию повторно используемого кода.
Основное отличие состоит в том, что функции предназначены для выполнения вычислений и по умолчанию всегда возвращают значения. А модули – для создания и трансформации геометрии. Выбор между функцией и модулем зависит от того, как будут использоваться результаты вашего кода. Если вы хотите создать объект или преобразовать геометрию, то модуль может быть предпочтительным. Если вам нужно выполнить вычисления и получить результат, то функция может быть более подходящим выбором. Подробнее в нашей статье “модуль и функция – большая разница“.
В нашем с Вами скрипте мы будем создавать дополнительные модули. Синтаксис модуля достаточно прост:
module ModulName(){ ...}
Модуль создания кольца
Добавим в наш скрипт следующий модуль создания кольца:
// Модуль создания кольца
module RingModule(MHeight=10, WWidth=2, innerD=10){
difference(){
cylinder(MHeight, d = innerD+WWidth, center=true);
cylinder(MHeight+1, d = innerD, center=true);
}
}
Данный модуль создает отцентрованное по точке начала координат кольцо. Модулю передаются три переменные, которым присваивается значение по умолчанию.
- MHeight – высота кольца;
- WWidth – толщина кольца, разница между внутренним и наружним контуром;
- innerD – внутренний диаметр кольца.
Сам код модуля состоит состоит всего из трех функций. При помощи функции cylinder() мы создаем два цилиндра, вложенных друг в друга:
// Внешний цилиндр
cylinder(MHeight, d = innerD+WWidth, center=true);
// Внутренний цилиндр
cylinder(MHeight+1, d = innerD, center=true);
В каждую функцию(команду) cylinder() передаются параметры:
- высота (MHeight),
- диаметр ( d – обозначает диаметр, т.к. по умолчанию функция воспринимает данный параметр как радиус) – для внешнего – innerD+WWidth, для внутреннего – innerD,
- параметр центрирования center, который при значении “true” центрирует объект относительно точки начала координат.
Для внешнего цилиндра ширина диаметра будет равна внутреннему диаметру (innerD), увеличенному на толщину стенки объекта (WWidth). Для внутреннего цилиндра ширина диаметра будет равна внутреннему диаметру (innerD).
Высоту внутреннего цилиндра мы целенаправленно увеличиваем на единицу (+1) для исключения неоднозначной интерпретации перекрытия нижней и верхней поверхностей отверстий при рендере.
При помощи функции difference(){…} вычитаем из внешнего цилиндра внутренний:
difference(){
// Внешний цилиндр
cylinder(MHeight, d = innerD+WWidth, center=true);
// Внутренний цилиндр
cylinder(MHeight+1, d = innerD, center=true);
}
Синтаксис функции difference() предполагает, что из первого объекта вычитаются последующие:
difference(){
cube(10); - основной объект
cube(20); - вычитаемый объект
cube(30); - вычитаемый объект
}
Чтобы создать кольцо с параметрами по умолчанию достаточно написать следующий код:
$fn =360;
RingModule();
Здесь $fn – это специальная переменная, которая отвечает за качество поверхности рендера. Чтобы получить гладкую поверхность – увеличиваем количество полигонов до 360. Если же требуется уменьшение нагрузки на расчеты достаточно указать параметры для меньшего числа полигонов. Например, 20 полигонов – $fn=20.
Результат выполнения кода:

Модуль создания пустого прямоугольника
Для создания прямоугольного сечения воспользуемся следующим модулем:
module HollowSquare(MHeight=10, WWidth=2, innerD1=10, innerD2=10){
difference(){
cube( [innerD1+WWidth,innerD2+WWidth,MHeight], center =true);
cube( [innerD1,innerD2,MHeight], center =true);
}
}
Модулю передаются следующие параметры (переменные):
- MHeight -высота объекта,
- WWidth -толщина стенки объекта,
- innerD1, innerD2 – внутренние размеры прямоугольника длина и ширина ( для квадрата будут одинаковы)
Код модуля аналогичен модулю кольца: при помощи функции difference(){…} из внешнего прямоугольника(куба) вычитается внутренний:
difference(){
// внешний куб
cube([innerD1+WWidth,innerD2+WWidth,MHeight], center =true);
// внутренний куб
cube([innerD1,innerD2,MHeight+1], center =true);
}
Функция Cube() моет получать следующие параметры:
cube([x,y,z], center =true);
где [x,y,z] – это параметры ширины, глубины, высоты, а сenter – булева переменная, которая при значении “true” центрирует объект относительно точки начала координат.
В данном примере для внешнего и внутреннего прямоугольников [x,y,z]:
| Внешний | Внутренний | |
| x | innerD1+WWidth | innerD1 |
| y | innerD2+WWidth | innerD2 |
| z | MHeight | MHeight+1 |
Таким образом, для внешнего прямоугольника параметры ширины и длины будут увеличены на толщину стенки (WWidth), а высота внутреннего прямоугольника будет увеличена на 1 единицу для исключения ошибок рендера.
Результат исполнения модуля:

Модуль создания перехода
Модуль перехода создает собственно переход межу кольцом и пустым квадратом. По факту он состоит из двух блоков создаваемых при помощи функции-модификатора hull(), вычитаемых друг из друга при помощи функции difference().
module Tunnel(MHeight=10, WWidth=2, innerD=10, innerD1=10, innerD2=10){
translate ([0,0,0.5])
difference(){
//внешний контур
hull(){
translate ([0,0, MHeight-1])
cylinder(1, d = innerD+WWidth, center =true);
cube([innerD1+WWidth,innerD2+WWidth,1], center =true);
}
//внутренний контур
hull(){
translate ([0,0, MHeight -1])
cylinder(2, d = innerD, center =true);
cube([innerD1,innerD2,2], center =true);
}
}
}
Модификатор hull() в OpenSCAD используется для создания объединенной формы из нескольких объектов. Он создает новый объект, путем натягивания оболочки на уже созданные объекты в пространстве.
Рассмотрим следующий код для создания внешнего контура:
hull(){
translate ([0,0, MHeight-1])
cylinder(1, d = innerD+WWidth, center =true);
cube([innerD1+WWidth,innerD2+WWidth,1], center =true);
}
Блок кода состоит из функции создания прямоугольника сube() и функции создания циллиндра cylinder(). Цилиндр смещен по оси Z на высоту MHeight. Т.к. мы создаем внешний контур переходника, то размеры и цилиндра, и куба увеличены на толщину стенки:
- для цилиндра диаметр равен innerD+WWidth,
- для куба ширина и глубина – innerD1+WWidth и innerD2+WWidth.
Результат использования модификатора hull() для ранее представленного кода будет выглядеть так:

На цилиндр, смещенный на высоту MHeight, и квадрат будет натянута общая обочка:

Второй блок создает внутренний контур переходника и также состоит из цилиндра и куба, только меньшего размера, на которые натянута общая оболочка:
//внутренний контур
hull(){
translate ([0,0, MHeight-1])
cylinder(1.1, d = innerD, center =true);
cube([innerD1,innerD2,1.1], center =true);
}
В результате вычитания двух фигур, полученных при помощи hull() получаем тунель-переходник:

Поскольку цилиндр и прямоугольника изначально отцентрованы относительно оси координат, то смещение цилиндра на MHeight вверх, приведет к формированию фигуры высотой: 0,5 высоты циллиндра + 0,5 высоты прямоугольника + MHeight, таким образом при высоте куба и цилиндра в 1 единицу, высота конечной фигуры составит MHeight +0,5*1 +0,5*1, или MHeight+1.
Для коррекции высоты фигуры, целесообразно сместить цилиндр на высоту MHeight – 1, тогда суммарная высота фигуры после команды Hull() как и составит MHeight.
Кроме того, учитывая, что изначально центры прямоугольника и цилиндра (каждый из которых высотой по 1 единице) расположены в точке начала координат, то для размещения на плоскости XY их нужно поднять на половину высоты, т.е. на 0.5, таким образом для расположения итоговой фигуры на плоскости XY требуется ее поднять на 0.5 единицы:
translate ([0,0,0.5])
Модуль создания переходника
Для создания финальной версии переходника используем ранее созданные модули:
module AdapterCircleSquare(MHeight=10, WWidth=1, innerD=10, innerD1=10, innerD2=10){
//Cглаживание объекта
$fn =180;
translate ([0,0, MHeight*0.5])
HollowSquare(MHeight, WWidth*2, innerD1, innerD2);
translate ([0,0, MHeight*1])
Tunnel(MHeight, WWidth*2, innerD, innerD1, innerD2);
translate ([0,0, MHeight*2.5])
RingModule(MHeight, WWidth*2, innerD);
}
AdapterCircleSquare(ModuleHeight, WallWidth,CircleInnerD, SquareInnerD1, SquareInnerD2);
В данном модуле мы поочередно вызываем модули:
- Модуль создания пустого квадрата HollowSquare();
- Модуль создания перехода-тунеля Tunnel();
- Модуль создания кольца RingModule();
Каждый из модулей выравнивается по оси Z при помощи модификатора Translate():
HollowSquare() – изначально отцентрован по отношению к точке начала координат, т.е. середина фигуры располагается на точке начала координат. Т.к. фигура симметричная, а ее высота равна ModuleHeight, то для размещения на плоскости XY ее нужно поднять на половину высоты ModuleHeight (0,5 MHeight), т.е.:
translate ([0,0, MHeight*0.5])
Tunnel() – т.к. высота HollowSquare() равна 1 ModuleHeight, а фигура, полученная в результате модуля Тunnel() размещена на плоскости XY, то ее смещение по оси Z будет равно MHeight:
translate ([0,0, MHeight])
RingModule() – также отцентрован по отношению к оси координат, для расположения на плоскости XY, ее нужно поднять на 0.5 ModuleHeight, кроме того ее нужно поднять на высоту HollowSquare() +Tunnel(), высота которых равна 2 ModuleHeight, т.о. получаем 2.5 ModuleHeight.
translate ([0,0, MHeight*2.5])

Финальная версия скрипта
Ниже привожу полный код скрипта.
// SCAD скрипт для создания переходника из квадратного сечения в круглое.
// Автор: 3d4p.ru
//Ширина стенки переходника, умноженная на 2.
WallWidth = 2;
//Высота концевых участков переходника
ModuleHeight =15;
//Внутренний диаметр переходника
// круглая часть
CircleInnerD = 10;
//квадратная часть размеры прямоугольника
SquareInnerD1 =10;
SquareInnerD2 =10;
// Модуль создания кольца
module RingModule(MHeight=10, WWidth=2, innerD=10){
difference(){
cylinder(MHeight, d = innerD+WWidth, center=true);
cylinder(MHeight+1, d = innerD, center=true);
}
}
// Модуль создания пустого прямоугольника
module HollowSquare(MHeight=10, WWidth=2, innerD1=10, innerD2=10){
difference(){
cube([innerD1+WWidth,innerD2+WWidth,MHeight], center =true);
cube([innerD1,innerD2,MHeight+1], center =true);
}
}
// Модуль создания перехода
module Tunnel(MHeight=10, WWidth=2, innerD=10, innerD1=10, innerD2=10){
translate ([0,0,0.5])
difference(){
//внешний контур
hull(){
translate ([0,0,MHeight-1])
cylinder(1, d = innerD+WWidth, center =true);
cube([innerD1+WWidth,innerD2+WWidth,1], center =true);
}
//внутренний контур
hull(){
translate ([0,0,MHeight-1])
cylinder(1.1, d = innerD, center =true);
cube([innerD1,innerD2,1.1], center =true);
}
}
}
module AdapterCircleSquare(MHeight=10, WWidth=1, innerD=10, innerD1=10, innerD2=10){
//Cглаживание объекта
$fn =180;
translate ([0,0, MHeight*0.5])
HollowSquare(MHeight, WWidth*2, innerD1, innerD2);
translate ([0,0, MHeight])
Tunnel(MHeight, WWidth*2, innerD, innerD1, innerD2);
translate ([0,0, MHeight*2.5])
RingModule(MHeight, WWidth*2, innerD);
}
//color("yellow", 0.7)
AdapterCircleSquare (ModuleHeight, WallWidth,CircleInnerD, SquareInnerD1, SquareInnerD2);








Много новой информации, даже не ожидала, что
узнаю столько всего полезного!