Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Скругления и Фаски: Эстетика и Функциональность

Recommended resources

The freely available resources this lesson will direct you to.

Здравствуйте!

В прошлых уроках мы создали корпус с различными функциональными вырезами: для светодиодов, кнопок, кабелей. Однако все рёбра и углы нашей модели остались острыми. Это не только делает её вид "незавершённым", но и может быть непрактично: острые края хрупки, о них можно поцарапаться, а некоторые элементы (вроде винтов или кнопок) сложнее вставлять в отверстия с острыми кромками.

Цель этого урока — научиться применять скругления (fillets) и фаски (chamfers). Мы рассмотрим, как эти операции улучшают эстетику и функциональность модели, и, что самое важное, как точно выбирать рёбра для их применения в build123d.

1. Что такое скругления и фаски и зачем они нужны?

В CAD-моделировании скругление и фаска — это две базовые операции для обработки рёбер объекта.

  • Скругление (Fillet) заменяет острое ребро дугой окружности, создавая плавный переход.
  • Фаска (Chamfer) срезает ребро под углом, создавая плоский скос.
Схемы скруглений (Fillet) и фасок (Chamfer)
Наглядное различие между внешними и внутренними скруглениями (fillets) и фасками (chamfers).

В контексте 3D-печати корпусов для электроники они выполняют несколько ключевых функций:

  1. Прочность: Внутренние скругления (например, у основания стенок) распределяют механическое напряжение и значительно снижают риск появления трещин.
  2. Эргономика и безопасность: Внешние скругления делают корпус приятнее на ощупь и убирают острые грани.
  3. Простота сборки: Небольшая фаска на входе в отверстие направляет винт, кнопку или вал, облегчая их установку.
  4. Эстетика: Модели со скруглёнными рёбрами выглядят более профессионально и "законченно".
  5. Качество печати: Правильно применённые фаски на нижних рёбрах модели помогают бороться с эффектом "слоновьей ноги" (небольшое утолщение первых слоёв) и улучшают внешний вид.

2. Базовое применение: fillet() и chamfer()

В build123d скругления и фаски применяются как методы к объекту Part. В простейшем случае, если не указывать, какие рёбра обрабатывать, операция применится ко всем рёбрам объекта.

Давайте создадим простой куб и скруглим все его рёбра.

from build123d import *

with BuildPart() as p:
    Box(10, 10, 10)
    # Применяем скругление радиусом 1 мм ко всем рёбрам
    fillet(radius=1) 

if "show_object" in locals():
    show_object(p.part)

Аналогично работает chamfer(length=1). Такой подход полезен редко, так как обычно требуется обработать только определённые рёбра.

3. Выборочное применение: ключ к точному моделированию

Самая важная часть работы с fillet и chamfer — это точный выбор рёбер. Как вы уже знаете из предыдущих уроков, build123d использует цепочки методов для фильтрации и выбора элементов топологии.

Методы fillet и chamfer принимают первым аргументом список рёбер для обработки.

fillet(edges_to_fillet, radius=...)

Чтобы получить этот список, мы используем коллекцию part.edges() и применяем к ней фильтры. Давайте модифицируем наш корпус из предыдущих уроков.

Задача: Скруглить внешние вертикальные рёбра и верхний внешний периметр корпуса.

# enclosure_v19.py
from build123d import *

# ================== ПАРАМЕТРЫ ==================
enclosure_length = 100
enclosure_width = 80
enclosure_height = 40
wall_thickness = 2
fillet_radius = 3

# ================== МОДЕЛИРОВАНИЕ ==================

with BuildPart() as enclosure:
    Box(enclosure_length, enclosure_width, enclosure_height)
    offset(amount=-wall_thickness, openings=enclosure.faces().sort_by(Axis.Z)[-1])

    # 1. Выбираем вертикальные рёбра
    vertical_edges = enclosure.edges().filter_by(Axis.Z)
    
    # 2. Выбираем рёбра верхнего внешнего контура
    top_face = enclosure.faces().sort_by(Axis.Z)[-1]
    # Получаем внешний контур (wire) и его рёбра
    top_outer_edges = top_face.outer_wire().edges()

    # 3. Применяем скругление к объединенному списку рёбер
    fillet(vertical_edges + top_outer_edges, radius=fillet_radius)

if "show_object" in locals():
    show_object(enclosure.part)

Разбор кода:

  1. enclosure.edges().filter_by(Axis.Z): Этот фильтр выбирает все рёбра, которые параллельны оси Z. В нашем случае это четыре вертикальных угла коробки.
  2. top_face.outer_wire().edges(): Мы сначала находим верхнюю грань, затем получаем её внешний контур (outer_wire) и из него извлекаем все рёбра.
  3. vertical_edges + top_outer_edges: Мы просто объединяем два списка рёбер, чтобы применить операцию за один вызов.

4. Продвинутый отбор рёбер: group_by

Что делать, если нужно выбрать рёбра не по ориентации, а по другим свойствам, например, радиусу (для отверстий) или длине? Здесь на помощь приходит мощный метод group_by. Он группирует элементы по значению некоторого свойства.

Задача: Добавить фаску на край отверстия для кнопки.

Представим, что мы создали корпус с отверстием под кнопку, как в прошлом уроке. Нам нужно выбрать только то ребро, которое является внешним контуром этого отверстия на лицевой панели, и применить к нему фаску.

Если мы знаем диаметр отверстия (button_head_dia), мы можем найти все круглые рёбра и сгруппировать их по радиусу.

# enclosure_v20.py
from build123d import *

# ================== ПАРАМЕТРЫ ==================
enclosure_length = 100
enclosure_width = 80
enclosure_height = 40
wall_thickness = 2

button_pos = (0, 15)
button_body_dia = 7
button_head_dia = 10
button_head_depth = 1.5

chamfer_size = 0.5

# ================== МОДЕЛИРОВАНИЕ ==================
with BuildPart() as enclosure:
    Box(enclosure_length, enclosure_width, enclosure_height)
    offset(amount=-wall_thickness, openings=enclosure.faces().sort_by(Axis.Z)[-1])
    
    side_face = enclosure.faces().sort_by(Axis.Y)[-1]
    
    # Создаем ступенчатое отверстие
    with Locations(side_face.center()):
        with BuildSketch() as button_hole:
            with Locations(button_pos):
                Circle(button_body_dia / 2)
        extrude(amount=-wall_thickness, mode=Mode.SUBTRACT)

        with BuildSketch() as button_counterbore:
            with Locations(button_pos):
                Circle(button_head_dia / 2)
        extrude(amount=-button_head_depth, mode=Mode.SUBTRACT)

    # Выбираем рёбра для фаски
    # 1. Находим все круглые рёбра
    circular_edges = enclosure.edges().filter_by(GeomType.CIRCLE)
    
    # 2. Группируем их по радиусу и выбираем группу с радиусом шляпки кнопки
    # group_by возвращает словарь {радиус: [рёбра]}
    edges_by_radius = circular_edges.group_by(Edge.radius)
    hole_edges = edges_by_radius[button_head_dia / 2]
    
    # 3. Уточняем выбор: нам нужно ребро на внешней грани
    target_edge = [e for e in hole_edges if e.face() == side_face]

    # 4. Применяем фаску
    chamfer(target_edge, length=chamfer_size)

if "show_object" in locals():
    show_object(enclosure.part)

Разбор кода:

  • filter_by(GeomType.CIRCLE) отбирает только круглые рёбра.
  • group_by(Edge.radius) создаёт словарь, где ключи — это радиусы, а значения — списки рёбер с этим радиусом.
  • edges_by_radius[button_head_dia / 2] позволяет нам получить список рёбер нужного нам диаметра. Поскольку у ступенчатого отверстия есть два круглых ребра с таким диаметром (на поверхности и на дне углубления), нам нужно выбрать то, что лежит на side_face.
  • Списковое включение [e for e in hole_edges if e.face() == side_face] элегантно решает эту задачу.

Такой подход, основанный на свойствах геометрии, чрезвычайно надёжен. Он будет работать, даже если вы переместите отверстие или измените геометрию корпуса, в отличие от выбора по координатам.

Group Examples — build123d documentation

В официальной документации build123d есть отличный пример, который демонстрирует использование group_by с Edge.Length и Edge.radius для выборочного применения скруглений и фасок. Рекомендую ознакомиться с ним, чтобы закрепить понимание этого мощного механизма.

На странице найдите раздел 'Properties with Keys'. Обратите внимание, как сначала выбираются рёбра для скругления по их известной длине (Edge.Length), а затем — круглые рёбра для фасок по их радиусу (Edge.radius).

5. Функциональные скругления и фаски для FDM-печати

Применение этих операций — не только вопрос эстетики.

Сравнение качества 3D-печати скруглений: Fillet против Chamfillet
Сравнение качества печати нижней кромки детали. Слева — обычное скругление (fillet), которое создаёт сложный для печати нависающий угол. Справа — комбинация фаски и скругления ('Chamfillet'), дающая более гладкую и качественную поверхность.
  • Фаска на нижнем ребре: Вместо скругления на рёбрах, соприкасающихся со столом принтера, часто лучше использовать фаску под углом 45°. Она печатается без поддержек и помогает скрыть дефекты первого слоя.
  • Внутренние скругления: Добавление небольшого скругления в месте стыка стенки и дна корпуса (внутренний угол) делает деталь значительно прочнее. Это одно из главных правил проектирования деталей под литьё пластиков, которое отлично работает и для FDM-печати.
Проверьте себя!

Вы хотите добавить скругления на все восемь рёбер (4 верхних, 4 нижних) плоской детали, похожей на крышку. При этом скругления на верхних рёбрах должны иметь радиус 2 мм, а на нижних — 1 мм. Как бы вы это сделали в build123d за два вызова fillet?

Показать ответ
  1. Создать деталь (например, Box).
  2. Выбрать верхнюю грань: top_face = my_part.faces().sort_by(Axis.Z)[-1].
  3. Выбрать рёбра верхней грани: top_edges = top_face.edges().
  4. Применить первое скругление: fillet(top_edges, radius=2).
  5. Аналогично выбрать нижнюю грань и её рёбра: bottom_face = my_part.faces().sort_by(Axis.Z)[0], bottom_edges = bottom_face.edges().
  6. Применить второе скругление: fillet(bottom_edges, radius=1).

Важно, что build123d (и ядро OCCT) корректно обрабатывает последовательные операции, перестраивая геометрию после каждого шага.

Ключевые выводы

  • Скругления (fillet) и фаски (chamfer) — это финальные штрихи, которые придают модели прочность, функциональность и законченный вид.
  • Ключевая задача при их применении — точный выбор рёбер. Используйте для этого фильтры (filter_by, sort_by) и группировку (group_by).
  • Отбор по геометрическим свойствам (GeomType, Edge.radius, Edge.Length) является наиболее надёжным и параметрическим подходом.
  • При проектировании для FDM-печати учитывайте, как скругления и фаски будут влиять на процесс печати, особенно на первых слоях и нависающих элементах.

Что дальше?

Мы завершили седьмой модуль, научившись создавать и дорабатывать все основные вырезы и отверстия. Теперь вы владеете полным набором инструментов для моделирования монолитных объектов.

В следующем модуле мы перейдём к самой сути нашей задачи: проектированию двухсоставного корпуса. Мы начнём с создания внешнего "монолита", затем сделаем его полым и, наконец, разделим на основание и крышку — основу для нашего финального проекта.

Can't find a good explanation? Sign up and we'll make it for you

Sign up