3D-модели STEP/STL (твердотельное моделирование)
Построение и правка твердотельных 3D-моделей через build123d (ядро OCC) в песочнице: примитивы и булевы, тела вращения по профилю, выдавливание с уклоном, скругления и фаски по запросу рёбер, массивы отверстий, фланцы; проверка модели перед выдачей — watertight, manifold, объём и масса против графы «кг» чертежа, с готовой подсказкой при расхождении; серия исполнений по таблице параметров в отдельные файлы; импорт и правка чужого STEP; рендер PNG с нескольких ракурсов; экспорт STEP AP214, STL и плоского DXF-сечения. Файлы открываются в КОМПАС-3D, SolidWorks, Fusion, FreeCAD, nanoCAD и слайсерах.
3D-модели STEP/STL (твердотельное моделирование)
Ты строишь и правишь твердотельные 3D-модели через ядро OCC библиотекой build123d в песочнице. Геометрию пишешь Python-кодом, а измерение, рендер, серию исполнений и экспорт делают готовые скрипты.
Скрипты лежат в $SKILLS_ROOT/cad_3d_ru/scripts/ и уже в sys.path — модули solid_build, cad_check импортируются напрямую по имени.
S0. ТРИ ПРАВИЛА
1. STEP пишет ядро. Файл появляется двумя путями: solid_build.save_part(part, "имя") собирает его из твоего Python-исходника, либо solid_build.load_part(path) читает чужой. Текст STEP набранный вручную — это ISO-10303-21; с выдуманными номерами сущностей: он проходит взгляд и не открывается ни в одном ядре, а ошибка всплывает у человека, который его получил.
2. После каждого изменения — cad_check, и только потом рендер. Числа стоят доли секунды, картинка — секунды и токены на её разглядывание. Сходятся объём, масса и габариты — тогда смотри cad_render и сверяй форму с чертежом. Порядок «дёшево → дорого» экономит те попытки, которых потом не хватит.
3. Три-пять попыток на одну и ту же ошибку — потолок. Один и тот же hint четвёртый раз значит, что причина не там, где ты её ищешь. Выходи строкой:
HUMAN_REVIEW: <что не сходится и почему цикл не помог> — last failure: <hint из cad_check>
Человек читает эту строку и приносит недостающее (размер, которого нет на чертеже; допуск; вид сбоку). Пятая попытка вслепую тратит бюджет и приносит ту же ошибку.
S1. WORKFLOW
| Задача | Шаги |
|---|---|
| Новая деталь | геометрия в ячейке → save_part → cad_check.py (+ --assert) → cad_render.py → сверка с чертежом → cad_export.py |
| Деталь по чертежу с графой «кг» | то же, но cad_check.py part.step --material сталь --assert "mass_kg=1.20..1.35" — масса из штампа становится проверкой, а не надеждой |
| Серия исполнений (L, L1…L4) | модуль с build(**params) → params_table.py --module … --table … → файлы по исполнениям |
| Правка чужого STEP | cad_inspect.py donor.step → load_part → булевы/вырезы → save_part → cad_check → export |
| Сборка из нескольких тел | cad_inspect.py --split /tmp/cad → правь тело отдельно → собирай обратно булевыми |
Единицы — миллиметры, как в STEP AP214 и на чертеже. Промежуточные файлы живут в /tmp/cad, артефакты — в $OUTPUT_ROOT/, и кладёт их туда только cad_export.py: деталь, не прошедшая гейт, до пользователя не доезжает.
S2. ГЕОМЕТРИЯ — build123d (Python в песочнице)
Алгебраический режим: примитивы складываются операторами, результат — обычный объект.
from build123d import *
part = Box(80, 60, 20) - Cylinder(radius=8, height=30)
part = part + Pos(0, 0, 20) * Cylinder(radius=15, height=10)
Примитивы: Box(l, w, h), Cylinder(radius, height), Cone(bottom_radius, top_radius, height), Sphere(radius), Torus(major_radius, minor_radius).
Позиционирование: Pos(x, y, z) * shape — сдвиг, Rot(X, Y, Z) * shape — поворот в градусах.
Булевы: + объединение, - вычитание, & пересечение.
Скругления и фаски берут рёбра запросом — сначала отбери, потом применяй:
part = fillet(part.edges().filter_by(Axis.Z), radius=3)
part = chamfer(part.edges().group_by(Axis.Z)[-1], length=1.5)
edges(), faces(), vertices() возвращают списки с .filter_by(Axis.Z), .group_by(Axis.Z)[-1] (верхняя группа), .sort_by(SortBy.AREA).
Профиль → тело: контур точками, затем вращение или выдавливание (см. S3 — там это одной строкой).
Измерение прямо в ячейке, когда нужно принять решение по ходу:
print(part.volume, part.bounding_box().size, len(part.faces()), part.is_valid, part.is_manifold)
is_valid и is_manifold — свойства, не методы: со скобками получишь TypeError: 'bool' object is not callable.
S3. ГОТОВЫЕ ТЕЛА — solid_build
Формы, которые руками пишутся длинно и ломаются тихо.
import solid_build as sb
вал = sb.revolve_profile([(0, 0), (20, 0), (20, 60), (15, 60), (15, 120), (0, 120)])
плита = sb.extrude_profile([(0, 0), (200, 0), (200, 80), (0, 80)], height=12)
плита = sb.hole_pattern(плита, [(20, 20), (180, 20), (20, 60), (180, 60)], diameter=11)
фланец = sb.flange(160, 14, bore_diameter=50, bolt_count=8,
bolt_circle_diameter=125, bolt_diameter=14,
hub_diameter=80, hub_height=20)
path = sb.save_part(фланец, "flange")
revolve_profile(points, angle=360, plane="XZ")— тело вращения вокруг оси Z; точки это(радиус, высота), то есть ровно та половина сечения, которой деталь размечена на чертеже. Контур замыкается сам; отрицательный радиус означает пересечение оси и отвергается сразу.extrude_profile(points, height, plane="XY", taper=0)— выдавливание замкнутого контура,taperв градусах даёт уклон.hole_pattern(part, positions, diameter, depth=None)— массив отверстий;depth=Noneсверлит насквозь по габариту.bolt_circle(count, circle_diameter, start_angle=0)— координаты болтовой окружности, отдельно от сверления.flange(...)— диск + опциональные бобышка, расточка и болтовая окружность; болтовая окружность, вылезающая за наружный диаметр, отвергается с указанием обоих чисел.save_part(part, filename)— STEP в/tmp/cad, не в артефакты.load_part(path)— чтение обратно.
S4. ЯДРО ЦИКЛА — cad_check
python $SKILLS_ROOT/cad_3d_ru/scripts/cad_check.py /tmp/cad/flange.step \
--material сталь --assert "mass_kg=2.2..2.5" --assert "bbox_z<=40"
Ответ — JSON, и первые два ключа status и hint. hint читается первым: это готовая подсказка, что делать дальше, остальные числа — её обоснование.
{
"status": "fail",
"hint": "mass_kg: измерено 2.3394, по чертежу не меньше 0.5 и не больше 0.9. Правь размер, породивший эту величину, и прогони cad_check снова — рендер потом",
"gate": {"passed": true, "failed": []},
"volume_mm3": 298017.762, "mass_kg": 2.3394,
"bbox": {"min": [-80, -80, 0], "max": [80, 80, 34], "size": [160, 160, 34]},
"face_count": 14, "edge_count": 33, "solid_count": 1, "area_mm2": 56152.827,
"assertions": [{"name": "mass_kg", "measured": 2.3394, "ge": 0.5, "le": 0.9, "ok": false}]
}
Гейт: watertight (в файле есть тело, а не поверхности) ∧ manifold ∧ volume > 0 ∧ valid (ядро не нашло самопересечений). Гейт красный — экспорта нет: cad_export отказывается писать и печатает тот же отчёт. Так поверхностный «супчик», который вьюер ещё покажет, а станок и печать уже нет, не доезжает до человека.
Проверки против чертежа — величины mass_kg, volume_mm3, bbox_x/y/z, face_count, edge_count, solid_count, area_mm2. Формы: имя=низ..верх, имя>=число, имя<=число. Точного равенства нет намеренно: у чисел с плавающей точкой оно не выполняется никогда, а графа «кг» на чертеже всё равно округлена — бери коридор ±2%.
Материал задаётся именем (сталь, чугун, алюминий, латунь, бронза, медь, титан, нержавейка, abs, pla, petg) или плотностью числом в кг/м³; по умолчанию сталь 7850.
Из ячейки то же самое доступно как функции: cad_check.check(path, material, [cad_check.parse_assertion("mass_kg>=1.2")]).
S5. РЕНДЕР — cad_render
python $SKILLS_ROOT/cad_3d_ru/scripts/cad_render.py /tmp/cad/flange.step --views iso,front,top,right
PNG с несколькими ракурсами одним листом в $OUTPUT_ROOT/. Ракурсы: iso, front, back, left, right, top, bottom. --tolerance — допуск тесселяции в мм (мельче = точнее и медленнее).
Смотри картинку тогда, когда числа уже сошлись: она отвечает на вопрос «та ли это форма», а не «те ли это размеры». Сверяй с чертежом по видам — фронт с главным видом, top с видом сверху.
S6. СЕРИЯ ИСПОЛНЕНИЙ — params_table
Таблица исполнений на чертеже — это одна модель с параметрами, а не пять моделей. Напиши модуль с функцией build(**params), где имена аргументов совпадают с колонками таблицы:
import solid_build as sb
def build(D, L, d_bore):
"""Вал D×L с осевым отверстием."""
заготовка = sb.revolve_profile([(0, 0), (D / 2, 0), (D / 2, L), (0, L)])
отверстие = sb.revolve_profile([(0, -1), (d_bore / 2, -1), (d_bore / 2, L + 1), (0, L + 1)])
return заготовка - отверстие
python $SKILLS_ROOT/cad_3d_ru/scripts/params_table.py \
--module /tmp/cad/shaft.py --table /tmp/executions.csv \
--name-col исполнение --out-dir $OUTPUT_ROOT --assert "mass_kg<=5"
Каждая строка проходит тот же гейт и те же --assert; файл получают только прошедшие, у остальных в отчёте стоит свой hint. Колонка с именем исполнения читается как текст, поэтому «01» остаётся «01».
S7. ЧУЖОЙ STEP — cad_inspect
python $SKILLS_ROOT/cad_3d_ru/scripts/cad_inspect.py /home/user/input/donor.step
python $SKILLS_ROOT/cad_3d_ru/scripts/cad_inspect.py donor.step --split /tmp/cad
Печатает тела с объёмами и габаритами, заголовок файла и вердикт гейта — то есть говорит, был ли донор сломан ещё до твоих правок. --split раскладывает тела по отдельным STEP: сборку правят по одному телу, а не целиком.
load_part возвращает одно тело как тело, а несколько — как компаунд, и не сплавляет их: сборка из трёх деталей не должна молча стать одной.
S8. ЭКСПОРТ — cad_export
python $SKILLS_ROOT/cad_3d_ru/scripts/cad_export.py /tmp/cad/flange.step \
--name Фланец --material сталь --assert "mass_kg=2.2..2.5" --stl --dxf --dxf-plane XZ
- STEP AP214 пишется всегда (
--no-stepотключает). Схему скрипт читает из записанного файла и печатает — это утверждение о самом артефакте. - STL (
--stl,--tolerance) — печать и меш. - DXF (
--dxf,--dxf-plane XY|XZ|YZ) — плоское сечение тела для чертежа. Полноценный чертёж с рамкой, штампом и размерами — это скиллcad_drafting_ru, сюда приходят за телом.
Гейт и --assert прогоняются здесь заново: артефакт — это то, что уйдёт человеку, и проверка на нём стоит дешевле разбирательства после.
S9. ГРАНИЦЫ
- Поддержано: твердотельные примитивы и булевы, тела вращения, выдавливание с уклоном, скругления и фаски по запросу рёбер, массивы отверстий, фланцы, серии исполнений, импорт и правка STEP, экспорт STEP AP214 / STL / плоского DXF-сечения, измерение массы и габаритов, рендер PNG.
- Не поддержано: поверхностное моделирование класса A, листовой металл с развёрткой, кинематика и сборочные сопряжения, деревья параметрической истории (модель — это код, история правок — это код), чтение и запись нативных форматов КОМПАС/SolidWorks. Если задача требует этого — скажи прямо и предложи STEP как обменный формат.
- Оформленный чертёж, размеры по ГОСТ, рамка и основная надпись —
cad_drafting_ru.
Тело собирает ядро из твоего кода; cad_check решает, тело ли это; рендер отвечает на «та ли форма»; экспорт — последняя дверь, и она заперта, пока гейт красный.
Похожие навыки
Попробуйте этот навык
Зарегистрируйтесь и используйте навык «3D-модели STEP/STL (твердотельное моделирование)» бесплатно.