Здравствуйте!
В прошлом уроке мы сделали важный шаг: научились создавать одиночные вырезы на любой, даже наклонной, грани объекта с помощью локальных рабочих плоскостей (BuildSketch на Face). Это мощный прием, но он не очень эффективен, когда нужно создать десятки однотипных элементов — например, вентиляционную решетку или ряд крепежных отверстий.
Цель этого урока — объединить возможности build123d с фундаментальной мощью Python. Мы научимся программно создавать множественные копии элементов с помощью обычных циклов for. Этот навык позволит вам быстро генерировать сложные и повторяющиеся структуры, что является ключевым для проектирования функциональных корпусов.
1. Основа: цикл и Locations
Представим, что нам нужно сделать ряд из пяти отверстий на пластине. Вместо того чтобы пять раз описывать создание отверстия, мы можем использовать цикл. build123d предоставляет удобный контекстный менеджер Locations, который применяет заданное смещение ко всему, что создается внутри него. Комбинируя for и Locations, мы можем элегантно решить эту задачу.
Давайте создадим новый файл lesson11_loops.py и напишем код для создания ряда отверстий.
# lesson11_loops.py
from build123d import *
# Параметры для нашего дизайна
plate_len = 100
plate_width = 50
plate_height = 5
hole_radius = 4
hole_count = 5
hole_spacing = 20
with BuildPart() as part:
# Создаем базовую пластину
Box(plate_len, plate_width, plate_height)
# Выбираем верхнюю грань для нашего эскиза
top_face = part.faces().sort_by(Axis.Z)[-1]
with BuildSketch(top_face) as sketch:
# Теперь самое интересное: создаем ряд окружностей
# Мы хотим, чтобы ряд был по центру. Начальная точка:
start_x = -((hole_count - 1) * hole_spacing) / 2
for i in range(hole_count):
# Вычисляем x-координату для каждого отверстия
x_pos = start_x + i * hole_spacing
# Используем Locations для позиционирования
# Внутри этого блока все координаты будут смещены на (x_pos, 0)
with Locations((x_pos, 0)):
Circle(hole_radius)
# Выдавливаем все окружности из эскиза, создавая сквозные отверстия
extrude(amount=-plate_height, mode=Mode.SUBTRACT)
# Отображаем результат
show_object(part.part, name="Plate with a row of holes")
Запустите этот код. Вы увидите пластину с идеально ровным рядом из пяти отверстий. Обратите внимание на ключевую идею: мы создали один эскиз (BuildSketch), но внутри него в цикле разместили несколько 2D-фигур (Circle) с помощью Locations. Затем одна операция extrude обработала их все. Этот подход гораздо эффективнее, чем создание нескольких отдельных эскизов.
2. Создание сетки (Grid) с помощью вложенных циклов
А что, если нам нужна не просто линия, а целая сетка отверстий, как в вентиляционной решетке? Здесь нам на помощь приходят вложенные циклы for. Один цикл будет отвечать за ряды (по оси Y), а другой — за столбцы (по оси X).
Дополним наш файл:
# lesson11_loops.py (продолжение)
from build123d import *
# ... (параметры можно переиспользовать или задать новые)
grid_rows = 5
grid_cols = 5
spacing = 15
with BuildPart() as grid_part:
Box(100, 100, 5)
with BuildSketch(grid_part.faces().sort_by(Axis.Z)[-1]) as grid_sketch:
# Вложенный цикл для создания сетки
for i in range(grid_cols):
x_pos = -((grid_cols - 1) * spacing) / 2 + i * spacing
for j in range(grid_rows):
y_pos = -((grid_rows - 1) * spacing) / 2 + j * spacing
with Locations((x_pos, y_pos)):
Circle(3)
extrude(amount=-5, mode=Mode.SUBTRACT)
# Закомментируйте предыдущий show_object, чтобы видеть только этот результат
# show_object(part.part, name="Plate with a row of holes")
show_object(grid_part.part, name="Plate with a grid of holes")
Этот код создаст пластину с сеткой отверстий 5x5. Точно так же можно создавать и массивы выступающих элементов, используя extrude в режиме Mode.ADD. Посмотрите на изображение ниже — такой массив столбиков разной высоты также можно сгенерировать программно с помощью циклов, добавляя третье измерение (например, из списка высот) в вашу логику.

3. Практический пример: макетная плата
Давайте создадим что-то, напоминающее печатную плату, как на изображении ниже. Это хороший пример, близкий к вашей конечной цели. Мы сделаем упрощенную версию: прямоугольник с двумя рядами отверстий по длинным сторонам.

Вот как это можно реализовать:
# lesson11_loops.py (третий пример)
from build123d import *
# Параметры платы
board_w = 80
board_l = 40
board_thk = 1.6 # Стандартная толщина текстолита
pin_hole_d = 1.0
pin_count = 15
pin_pitch = 2.54 # Стандартный шаг
row_offset_y = 15
with BuildPart() as pcb:
# Основа платы
Box(board_w, board_l, board_thk)
with BuildSketch(pcb.faces().sort_by(Axis.Z)[-1]) as pin_holes:
# Вычисляем начальную позицию для рядов, чтобы они были по центру
start_x = -((pin_count - 1) * pin_pitch) / 2
# Два ряда отверстий: один со смещением +row_offset_y, другой -row_offset_y
for y_loc in [-row_offset_y, row_offset_y]:
for i in range(pin_count):
x_loc = start_x + i * pin_pitch
with Locations((x_loc, y_loc)):
Circle(pin_hole_d / 2)
extrude(amount=-board_thk, mode=Mode.SUBTRACT)
# Закомментируйте предыдущие show_object
# show_object(grid_part.part, name="Plate with a grid of holes")
show_object(pcb.part, name="PCB Mockup")
Этот пример демонстрирует, как с помощью нескольких строк кода и циклов можно создать довольно сложную и упорядоченную геометрию, точно контролируя положение каждого элемента через параметры.
Проверьте себя!
Задание:
Создайте круглую пластину (цилиндр высотой 5 мм и радиусом 40 мм). На ее верхней поверхности сделайте 8 круглых отверстий (диаметром 5 мм), равномерно расположенных по окружности радиусом 30 мм.
Подсказка:
Вам понадобится вспомнить, как преобразовывать полярные координаты в декартовы. Для точки на окружности радиусом под углом :
Не забудьте, что функции math.cos() и math.sin() в Python принимают угол в радианах. Вам нужно будет импортировать модуль math.
Показать решение
# lesson11_exercise_solution.py
import math
from build123d import *
# Параметры
plate_radius = 40
plate_height = 5
hole_count = 8
hole_diameter = 5
pattern_radius = 30
with BuildPart() as part:
# Создаем круглую пластину
Cylinder(radius=plate_radius, height=plate_height)
# Выбираем верхнюю грань
top_face = part.faces().sort_by(Axis.Z)[-1]
with BuildSketch(top_face) as sketch:
# Цикл для создания отверстий по окружности
for i in range(hole_count):
# Вычисляем угол для каждого отверстия
angle_deg = (360 / hole_count) * i
angle_rad = math.radians(angle_deg)
# Преобразуем полярные координаты в декартовы
x = pattern_radius * math.cos(angle_rad)
y = pattern_radius * math.sin(angle_rad)
with Locations((x, y)):
Circle(radius=hole_diameter / 2)
extrude(amount=-plate_height, mode=Mode.SUBTRACT)
show_object(part.part, name="Circular Pattern of Holes")
Этот пример показывает, что с помощью циклов и базовой математики можно создавать не только прямоугольные, но и любые другие регулярные паттерны.
Ключевые выводы
- Стандартные циклы Python
for— ваш основной инструмент для создания повторяющихся элементов вbuild123d. - Контекстный менеджер
with Locations(...):используется для позиционирования фигур внутриBuildSketch. - Наиболее эффективный подход — создать один
BuildSketch, в нем с помощью циклов разместить все необходимые 2D-фигуры, а затем применить одну операциюextrude. - Вложенные циклы позволяют легко создавать двумерные массивы (сетки) элементов.
Что дальше?
Мы увидели, насколько гибкими могут быть циклы for. Вы можете реализовать любую логику для расположения элементов. Однако для самых распространенных случаев, таких как линейные и круговые массивы, в build123d существуют специальные, более высокоуровневые инструменты — паттерны (LinearPattern, CircularPattern). В следующем уроке мы рассмотрим их и сравним с подходом на основе циклов. Они могут сделать ваш код еще более кратким и читаемым.