Для создания дома-многоэтажки нам потребуются несколько несложных манипуляций.
Начнем с создания основы для многоэтажного дома в OpenSCAD. Для начала определим параметры дома, такие как высота, ширина и глубина.
height = 100;
width = 50;
depth = 30;
Далее, мы можем использовать функцию Cube для создания основы дома:
cube([width, depth, 5]); // base
Сначала определим высоту этажа:
floors = 5; // количество этажей
// высоту каждого этажа вычислим:
floor_height = (height - base_height - roof_height)/floors;
где height – общая высота, base_height – высота основания, roof_height – высота крыши, floors – число этажей
Теперь добавим несколько этажей, используя цикл for:
// генерируем этажи
translate ([0, 0, 5]) // каждый этаж смещен на высоту основания
for (f = [0:floors-1]) {
translate([0, 0, floor_height*f])
color ("blue", 1)
cube([width, depth, floor_height]);
}
Теперь, когда у нас есть основа и несколько этажей, можно добавить окна на каждом этаже, а также другие детали, такие как балконы или крыши.
Сначала добавим крышу:
//добавляем крышу
translate ([0, 0, base_height+floors*floor_height]) //смещаем основание крыши на высоту последнего этажа
color ("darkred", 1)
hull() {
// создаем основание
cube([width, depth, 1]);
// создаем верхнюю площадку крыши в 2 раза меньше по размерам
translate([width/4, depth/4, roof_height-2])
cube([width/2, depth/2, 1]);
}
В данной ситуации при помощи функции hull() создаем общую оболочку для двух прямоугольников разных размеров, получаем крышу

Теперь формируем окна, в данном примере они будут выпуклыми, но если воспользоваться функцией вычитания (difference() – подробнее в статье о булевых операциях), то окна будут вдавленными в конструкции.
Код модуля окна:
// Здесь переходим к генерации окон
module windows(invers = 0, winwidth=window_width, windepth=window_depth, winheight=window_height){
color ("lightblue", 1)
if (invers == 0){
cube([winwidth, windepth, winheight]);
} else{
cube([windepth, winwidth, winheight]);
}
} }
Учитывая, что окна можем использовать на двух сторонах дома, то для определения направления вводим функцию инверсии в коде модуля ( поскольку модуль учебный, то будем опробывать данную функцию), на практике логичнее использовать rotate().

Следующие четыре блока аналогичны друг другу и генерируют сетку окон на 4-х сторонах фигуры. Рассмотрим первый модуль:
// Передние окна
for (f = [0:1:floors-1]){
translate ([0,0, f*floor_height+base_height])
for (w = [0:1:windows_L-1]) {
translate([interwindow_L+w*(interwindow_L+window_width), -(window_depth/2), interwindow_H])
windows();
}
}

Полная версия скрипта выглядит так:
//Полный скрипт многоэтажки
// Высота, длина, глубина многоэтажки
height = 100;
width = 50;
depth = 30;
base_height = 5; // высота основания
roof_height = 10; // высота крыши
floors = 5; // количество этажей
windows_L = 4; // количество окон на этаже на широкой стороне
windows_S = 1; // количество окон на этаже на узкой стороне
// Размеры окна
window_width = 10;
window_height = 10;
window_depth = 4;
// производные переменные:
// высота каждого этажа
floor_height = (height - base_height-roof_height)/floors;
// промежутки между окнами
// промежуток от края до окна и между окнами
// на узкой стороне
interwindow_S = (depth - window_width*windows_S)/(windows_S+1);
// на широкой стороне
interwindow_L = (width - window_width*windows_L)/(windows_L+1);
// между краем этажа
interwindow_H = (floor_height-window_height)/2;
//создаем основание
cube([width, depth, base_height]);
// генерируем этажи
translate ([0, 0, base_height])
for (f = [0:floors-1]) {
translate([0, 0, floor_height*f])
color ("pink", 1)
cube([width, depth, floor_height]);
}
//добавляем крышу
translate ([0, 0, base_height+floors*floor_height])
color ("darkred", 1)
hull() {
cube([width, depth, 1]);
translate([width/4, depth/4, roof_height-2])
cube([width/2, depth/2, 1]);
}
// Здесь переходим к генерации окон
module windows(invers = 0, winwidth=window_width, windepth=window_depth, winheight=window_height){
color ("lightblue", 1)
if (invers == 0){
cube([winwidth, windepth, winheight]);
} else{
cube([windepth, winwidth, winheight]);
}
}
// Передние окна
for (f = [0:1:floors-1]){
translate ([0,0, f*floor_height+base_height])
for (w = [0:1:windows_L-1]) {
translate([interwindow_L+w*(interwindow_L+window_width), -(window_depth/2), interwindow_H])
windows();
}
}
// Задние окна
for (f = [0:1:floors-1]){
translate ([0,depth, f*floor_height+base_height])
for (w = [0:1:windows_L-1]) {
translate([interwindow_L+w*(interwindow_L+window_width), -(window_depth/2), interwindow_H])
windows();
}
}
//боковые окна слева
for (f = [0:1:floors-1]){
translate ([0, 0, f*floor_height+base_height])
for (w = [0:1:windows_S-1]) {
translate([-(window_depth/2), interwindow_S+w*(interwindow_S+window_width), interwindow_H])
windows(1);
}
}
//боковые окна справа
for (f = [0:1:floors-1]){
translate ([width, 0, f*floor_height+base_height])
for (w = [0:1:windows_S-1]) {
translate([-(window_depth/2), interwindow_S+w*(interwindow_S+window_width), interwindow_H])
windows(1);
}
}







