Здравствуйте!
В предыдущем уроке мы заложили основу для точного проектирования, научившись размещать и вращать объекты в глобальной системе координат с помощью Location и Rotation. Мы могли поместить объект в любую точку пространства с любой ориентацией. Это фундаментальный навык, но для решения многих практических задач, таких как создание отверстия в стенке корпуса, он может быть избыточным и неудобным. Вычислять абсолютные координаты центра отверстия на наклонной грани — сложная задача.
К счастью, есть более интуитивный подход. Вместо того чтобы работать в глобальных координатах, мы можем "прикрепить" временную 2D-систему координат прямо к нужной нам грани.
Цель этого урока — научиться создавать вырезы и отверстия на любой грани 3D-объекта с помощью локальных рабочих плоскостей. Этот метод значительно упрощает моделирование, позволяя нам думать в 2D-координатах на поверхности 3D-тела, что является ключевым шагом к проектированию вырезов для портов и вентиляционных решеток в нашем будущем корпусе.
1. Что такое рабочая плоскость (Workplane)?
Рабочая плоскость (в build123d она представлена классом Plane) — это, по сути, локальная 2D-система координат, существующая в 3D-пространстве. У нее есть свое начало (origin) и оси (X, Y, Z), которые могут быть смещены и повернуты относительно глобальных осей.
В контексте нашей задачи, самый удобный способ создать рабочую плоскость — это просто выбрать грань (Face) существующего объекта. build123d автоматически создаст плоскость, у которой:
- Начало координат будет в центре выбранной грани.
- Оси X и Y будут лежать в плоскости этой грани.
- Ось Z будет перпендикулярна (нормальна) к грани и направлена "наружу" от объекта.
С вашим опытом в физике, это можно представить как определение локальной системы отсчета на поверхности тела.
2. Выбор грани и создание эскиза
Чтобы нарисовать контур будущего отверстия, мы используем контекстный менеджер BuildSketch. При его создании мы указываем, на какой грани мы хотим работать.
Предположим, у нас есть простой Box, и мы хотим сделать круглое отверстие на его верхней грани.

Для выбора нужной грани мы можем использовать метод .faces(), который возвращает список всех граней объекта. Чтобы из этого списка выбрать конкретную грань, удобно использовать методы сортировки. Например, чтобы надежно выбрать самую верхнюю грань по оси Z, мы можем отсортировать все грани по их положению и взять последнюю.
Давайте напишем код. Создайте новый файл lesson10_workplanes.py:
# lesson10_workplanes.py
from build123d import *
# Создаем базовую деталь
with BuildPart() as part:
Box(50, 50, 20)
# 1. Выбираем верхнюю грань
# .faces() возвращает список всех граней объекта
# .sort_by(Axis.Z) сортирует их по положению центра вдоль оси Z
# [-1] выбирает последний элемент, т.е. самый верхний
top_face = part.faces().sort_by(Axis.Z)[-1]
# 2. Создаем эскиз на этой грани
with BuildSketch(top_face) as sketch:
# Теперь мы работаем в 2D-координатах на верхней грани.
# (0, 0) - это центр грани.
Circle(10)
# Добавим еще прямоугольник для наглядности
Rectangle(5, 30, align=(Align.CENTER, Align.CENTER))
# 3. Выдавливаем эскиз, чтобы создать вырез
# amount=-10 означает выдавливание на 10 мм "внутрь" детали
# mode=Mode.SUBTRACT указывает, что мы вычитаем геометрию, а не добавляем
extrude(amount=-10, mode=Mode.SUBTRACT)
show_object(part.part, name="Box with Cutouts")
Запустите этот код. Вы увидите куб с круглым и прямоугольным углублениями на верхней грани. Обратите внимание, как элегантно решается задача: мы не вычисляли никаких глобальных координат. Мы просто сказали: "на этой грани нарисуй круг и выдави его".
3. Работа с наклонными гранями
Истинная мощь этого подхода проявляется при работе с непараллельными глобальным осям поверхностями. Давайте повторим пример из прошлого урока — блок с наклонной ножкой, — но теперь сделаем отверстие в самой ножке. В данном случае, это будет просто наклонный блок.
# ... (продолжение файла lesson10_workplanes.py)
with BuildPart() as angled_part:
# Создаем блок и сразу поворачиваем его
Box(40, 40, 60, rotation=(0, -30, 0))
# Нам нужно выбрать наклонную грань.
# После поворота на -30 градусов вокруг Y, "передняя" грань
# стала самой дальней по оси X.
side_face = angled_part.faces().sort_by(Axis.X)[-1]
with BuildSketch(side_face) as side_sketch:
# Рисуем в центре этой наклонной грани
Circle(8)
# Выдавливаем "насквозь". amount можно сделать больше толщины стенки.
extrude(amount=-10, mode=Mode.SUBTRACT)
# show_object(angled_part.part, name="Angled Part with Hole")
В этом примере мы создали повернутый блок. Вычислить координаты центра отверстия на его наклонной грани с помощью Location было бы довольно утомительно (потребовалось бы применить тригонометрию). Вместо этого мы просто выбрали нужную грань, отсортировав все грани по оси X, и создали на ней эскиз. build123d взял на себя всю "грязную работу" по преобразованию координат.
Выбор правильного критерия для sort_by() (Axis.X, Axis.Y, Axis.Z, или даже SortBy.AREA для выбора по площади) является частью процесса проектирования и зависит от геометрии вашей модели.
Проверьте себя!
Задание:
Создайте цилиндр (Cylinder) высотой 50 мм и радиусом 20 мм. Затем сделайте прямоугольный вырез размером 10x20 мм на его боковой, изогнутой поверхности. Вырез должен уходить вглубь на 5 мм.
Подсказка:
- Создайте
Cylinder. - Боковая поверхность цилиндра — это тоже
Face. Ее можно выбрать, например, отсортировав по площади (SortBy.AREA) и выбрав самую большую грань. - Создайте
BuildSketchна этой криволинейной грани.build123dавтоматически создаст рабочую плоскость, касательную к поверхности в ее центре. - Нарисуйте
Rectangleв этом эскизе. - Используйте
extrudeсmode=Mode.SUBTRACT.
Показать решение
# lesson10_exercise_solution.py
from build123d import *
# Параметры
cyl_h = 50
cyl_r = 20
cut_w = 10
cut_h = 20
cut_depth = -5
with BuildPart() as part:
# 1. Создаем цилиндр
Cylinder(radius=cyl_r, height=cyl_h)
# 2. Выбираем боковую грань. Она имеет наибольшую площадь.
side_face = part.faces().sort_by(SortBy.AREA)[-1]
# 3. Создаем эскиз на этой грани
with BuildSketch(side_face):
# 4. Рисуем прямоугольник
Rectangle(width=cut_w, height=cut_h)
# 5. Выдавливаем вырез
extrude(amount=cut_depth, mode=Mode.SUBTRACT)
show_object(part.part, name="Cylinder with side cutout")
Этот пример показывает, что BuildSketch можно применять даже к криволинейным поверхностям, что делает этот инструмент чрезвычайно гибким.
Ключевые выводы
- Локальные рабочие плоскости позволяют "рисовать" 2D-эскизы прямо на гранях 3D-объектов.
- Контекст
with BuildSketch(target_face):— основной инструмент для этой задачи. - Для программного выбора нужной грани (
Face) удобно использовать метод.faces().sort_by(...). - Все, что нарисовано внутри
BuildSketch, использует локальные 2D-координаты этой грани. - Комбинация
BuildSketchиextrude(mode=Mode.SUBTRACT)является стандартным способом создания отверстий и вырезов.
Что дальше?
Мы научились создавать одиночные, точно расположенные вырезы. Это уже огромный шаг вперед. Но что, если нам нужна вентиляционная решетка, состоящая из десятков одинаковых отверстий? Или ряд крепежных отверстий? Создавать каждое из них вручную было бы неэффективно.
В следующем уроке мы объединим мощь рабочих плоскостей с мощью Python: мы научимся создавать множественные копии элементов с помощью обычных циклов for, что позволит нам программно генерировать сложные паттерны и массивы.