Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a1d3f710d | ||
|
|
c0d650aef8 | ||
|
|
67d09d05c9 | ||
|
|
a1942b228d | ||
|
|
0720fd7397 | ||
|
|
94e044bd03 | ||
|
|
c62794b415 |
@@ -11,7 +11,7 @@
|
||||
{
|
||||
"name": "kompas",
|
||||
"source": "./plugin",
|
||||
"description": "Управление КОМПАС-3D из Claude Code: 85 MCP-инструментов (детали, эскизы, формообразующие операции, массивы, отверстия, сборки и сопряжения, 2D-чертежи, STEP/STL, осмотр модели) и два навыка — построение (kompas-3d) и проектирование под FDM-печать (kompas-fdm-design).",
|
||||
"description": "Управление КОМПАС-3D из Claude Code: 74 MCP-инструмента (детали, эскизы, формообразующие операции, массивы, отверстия, исполнения, внешний вид, сборки и сопряжения, 2D-чертежи, STEP/STL, осмотр модели) и два навыка — построение (kompas-3d) и проектирование под FDM-печать (kompas-fdm-design).",
|
||||
"category": "productivity",
|
||||
"keywords": ["cad", "kompas", "3d", "step", "mcp", "fdm"]
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@ STEP/STL, осмотр и измерение модели — плюс два н
|
||||
## Что нужно до установки
|
||||
|
||||
- **Windows x64** — сервер является COM-клиентом КОМПАС и работает только на той же машине;
|
||||
- **установленный КОМПАС-3D** (проверено на v24 Home) **с компонентом SDK**. Interop-сборки
|
||||
- **установленный КОМПАС-3D** (проверено на v25 Home, v24 Home тоже поддерживается) **с компонентом SDK**. Interop-сборки
|
||||
принадлежат АСКОН, в поставку не входят и берутся из установки
|
||||
(`SDK\Samples\CSharp.zip`, каталог `Common`); при первом запуске они распаковываются
|
||||
в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`. Если SDK не установлен, укажите каталог
|
||||
с этими сборками в переменной окружения `KOMPAS_INTEROP_DIR`;
|
||||
- **[.NET Runtime](https://dotnet.microsoft.com/download/dotnet) 8 или новее, x64** — сервер
|
||||
- **[.NET Runtime](https://dotnet.microsoft.com/download/dotnet) 10 или новее, x64** — сервер
|
||||
поставляется framework-dependent (2,3 МБ вместо 34), поэтому рантайм берётся с машины.
|
||||
Проверить: `dotnet --list-runtimes` должен показать `Microsoft.NETCore.App 8.x` или новее;
|
||||
Проверить: `dotnet --list-runtimes` должен показать `Microsoft.NETCore.App 10.x` или новее;
|
||||
- чекаут и рабочие файлы — вне синхронизируемых папок OneDrive.
|
||||
|
||||
Запускать КОМПАС заранее не нужно: сервер присоединится к открытому окну, а если его нет —
|
||||
@@ -48,7 +48,7 @@ STEP/STL, осмотр и измерение модели — плюс два н
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **MCP-сервер `kompas`** | 86 инструментов: документы, эскизы, выдавливание/вращение/по сечениям/по траектории, оболочка, рёбра, уклон, скругления и фаски, массивы и зеркало, отверстия, булевы операции, прямое редактирование B-rep, переменные и параметризация, **исполнения** (несколько геометрий одной модели в одном файле), сборки и сопряжения (в том числе по вспомогательным плоскостям и осям), 2D-чертежи (виды, размеры, обозначения, тех. требования), STEP/STL, осмотр (`describe_model`, `list_faces`, `list_edges`, `measure`) |
|
||||
| **MCP-сервер `kompas`** | 78 инструментов: документы, эскизы, выдавливание/вращение/по сечениям/по траектории, оболочка, рёбра, уклон, скругления и фаски, массивы и зеркало, отверстия, булевы операции, прямое редактирование B-rep, переменные и параметризация, **исполнения** (несколько геометрий одной модели в одном файле), внешний вид (цвет, прозрачность, текстуры), сборки и сопряжения (в том числе по вспомогательным плоскостям и осям), 2D-чертежи (виды, размеры, обозначения, тех. требования), STEP/STL, осмотр (`describe_model`, `list_faces`, `list_edges`, `measure`) |
|
||||
| **Навык `kompas-3d`** | методика построения: порядок работы, выбор подхода, проверенные приёмы и ловушки |
|
||||
| **Навык `kompas-fdm-design`** | проектирование под FDM/FFF-печать: нависания, толщины стенок, зазоры и посадки, ориентация, бобышки и защёлки |
|
||||
| **Команда `/kompas:doctor`** | диагностика установки |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "kompas",
|
||||
"displayName": "КОМПАС-3D",
|
||||
"version": "0.2.0",
|
||||
"version": "0.7.1",
|
||||
"description": "Управление КОМПАС-3D из Claude Code: детали, сборки, чертежи, STEP — через MCP-сервер",
|
||||
"author": {
|
||||
"name": "Shahovalov Mikhail",
|
||||
|
||||
+10
-3
@@ -6,16 +6,16 @@
|
||||
## Предпосылки
|
||||
|
||||
- Windows x64;
|
||||
- установленный КОМПАС-3D (проверено на v24 Home) — сервер является COM-клиентом, а не автономным
|
||||
- установленный КОМПАС-3D (проверено на v25 Home, v24 Home тоже поддерживается) — сервер является COM-клиентом, а не автономным
|
||||
CAD-движком, и работает только на той же машине. Запускать заранее не нужно: сервер присоединится
|
||||
к открытому окну, а если его нет — запустит экземпляр сам;
|
||||
- КОМПАС установлен **вместе с компонентом SDK**: interop-сборки принадлежат АСКОН, в поставку
|
||||
сервера не входят и берутся из установки (`SDK\Samples\CSharp.zip`, каталог `Common`). При первом
|
||||
запуске они распаковываются в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`; если SDK не установлен,
|
||||
укажите каталог с этими сборками в переменной окружения `KOMPAS_INTEROP_DIR`;
|
||||
- [**.NET Runtime**](https://dotnet.microsoft.com/download/dotnet) **8 или новее, x64** — сервер
|
||||
- [**.NET Runtime**](https://dotnet.microsoft.com/download/dotnet) **10 или новее, x64** — сервер
|
||||
поставляется framework-dependent, рантайм берётся с машины. Проверка: `dotnet --list-runtimes`
|
||||
показывает `Microsoft.NETCore.App 8.x` или новее;
|
||||
показывает `Microsoft.NETCore.App 10.x` или новее;
|
||||
- чекаут репозитория и рабочие файлы — вне синхронизируемых папок OneDrive.
|
||||
|
||||
## Установка
|
||||
@@ -38,6 +38,13 @@
|
||||
|
||||
Если инструменты остались прежними — `/reload-plugins`.
|
||||
|
||||
## Промпты и ресурсы
|
||||
|
||||
Сервер отдаёт готовые маршруты работы промптами — `part`, `import-edit-export`, `drawing`,
|
||||
`assembly` — и они появляются в меню slash-команд Claude Code как `/kompas:part (MCP)` и т. д.
|
||||
Справочник и сводка активной модели доступны ресурсами `kompas://help/<тема>` и
|
||||
`kompas://active/summary`; агент читает их сам, а подстановка через @-упоминание зависит от клиента.
|
||||
|
||||
## Разработка сервера
|
||||
|
||||
Переменная окружения `KOMPAS_MCP_EXE` подменяет поставленный бинарь своим:
|
||||
|
||||
@@ -4,7 +4,7 @@ Codex не знает ни маркетплейсов, ни `${CLAUDE_PLUGIN_ROO
|
||||
к каталогу плагина.
|
||||
|
||||
1. Склонировать `https://git.shahovalov.ru/mikhail/kompas-plugin.git` — сервер лежит внутри,
|
||||
в `plugin/bin/`, собирать ничего не нужно (требуется .NET Runtime 8+ x64).
|
||||
в `plugin/bin/`, собирать ничего не нужно (требуется .NET Runtime 10+ x64).
|
||||
2. Вставить `config.snippet.toml` в `~/.codex/config.toml`, заменив `<PLUGIN>` на абсолютный путь
|
||||
к каталогу `plugin/` клона. Лаунчер `scripts/launch-kompas-mcp.ps1` — тот же, что у плагина
|
||||
Claude Code.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Подключение к opencode
|
||||
|
||||
1. Склонировать `https://git.shahovalov.ru/mikhail/kompas-plugin.git` — сервер лежит внутри,
|
||||
в `plugin/bin/` (требуется .NET Runtime 8+ x64).
|
||||
в `plugin/bin/` (требуется .NET Runtime 10+ x64).
|
||||
2. Слить `opencode.json` со своим конфигом opencode, заменив `<PLUGIN>` на абсолютный путь к
|
||||
каталогу `plugin/` клона. Используется тот же лаунчер `scripts/launch-kompas-mcp.ps1`.
|
||||
3. Навыки: скопировать `plugin/skills/{kompas-3d,kompas-fdm-design}` в каталог навыков агента
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+477
-562
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,14 +1,15 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net8.0",
|
||||
"tfm": "net10.0",
|
||||
"rollForward": "LatestMajor",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "8.0.0"
|
||||
"version": "10.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
|
||||
"CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,14 +28,15 @@ description: "Диагностика установки плагина КОМП
|
||||
`/plugin update kompas@kompas-plugin`, затем `/reload-plugins`.
|
||||
|
||||
4. **.NET Runtime.** Сервер поставляется framework-dependent, поэтому рантайм нужен на машине:
|
||||
`dotnet --list-runtimes` должен показать строку `Microsoft.NETCore.App 8.<любая>` или новее
|
||||
`dotnet --list-runtimes` должен показать строку `Microsoft.NETCore.App 10.<любая>` или новее
|
||||
(x64). Ни одной подходящей строки или самой команды `dotnet` нет — это и есть причина сбоя
|
||||
пункта 3: попроси пользователя поставить .NET Runtime 8 или новее с
|
||||
пункта 3: попроси пользователя поставить .NET Runtime 10 или новее с
|
||||
https://dotnet.microsoft.com/download/dotnet (нужен именно x64; Desktop Runtime не обязателен).
|
||||
|
||||
5. **КОМПАС-3D установлен и, возможно, уже запущен.** Сервер подключается к КОМПАС лениво — не при
|
||||
старте MCP-сервера, а при первом вызове инструмента. Проверь двумя командами:
|
||||
`Get-Process KOMPAS* -ErrorAction SilentlyContinue` (запущен ли сейчас) и
|
||||
`Get-Process KOMPAS,kHome -ErrorAction SilentlyContinue` (запущен ли сейчас; у Home-редакции
|
||||
процесс называется `kHome`; имена точные — маска `KOMPAS*` поймала бы сам `kompas-mcp`) и
|
||||
`Get-ChildItem 'HKLM:\SOFTWARE\Classes\KOMPAS.Application.5' -ErrorAction SilentlyContinue`
|
||||
(зарегистрирован ли COM-класс, то есть установлен ли КОМПАС вообще). Запущен — сервер
|
||||
присоединится к нему; не запущен, но зарегистрирован — попробует запустить новый экземпляр сам;
|
||||
|
||||
@@ -40,7 +40,7 @@ catch {
|
||||
# Самая частая причина здесь — отсутствующий .NET Runtime: сервер поставляется
|
||||
# framework-dependent, и без рантайма apphost падает именно тут.
|
||||
[Console]::Error.WriteLine("kompas-mcp launcher: не удалось запустить сервер: $($_.Exception.Message)")
|
||||
[Console]::Error.WriteLine("kompas-mcp launcher: если .NET Runtime не установлен — https://dotnet.microsoft.com/download/dotnet (нужен .NET 8 или новее, x64)")
|
||||
[Console]::Error.WriteLine("kompas-mcp launcher: если .NET Runtime не установлен — https://dotnet.microsoft.com/download/dotnet (нужен .NET 10 или новее, x64)")
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
+215
-358
@@ -5,9 +5,10 @@ description: >
|
||||
модификация деталей, импорт/экспорт STEP, работа со сборками, осмотр геометрии
|
||||
снимками и запросами. Используй ВСЕГДА, когда задача — что-то СДЕЛАТЬ в КОМПАС
|
||||
через MCP-инструменты (создать/править деталь, импортировать STEP, разобрать
|
||||
сборку, померить, отрендерить, экспортировать). Здесь — playbook'и и эвристики,
|
||||
сборку, померить, раскрасить, отрендерить, экспортировать). Здесь — playbook'и и эвристики,
|
||||
проверенные на практике. Триггеры: «построй деталь в КОМПАС», «импортируй STEP»,
|
||||
«что в этой сборке», «нарасти/измени деталь», «экспортируй STEP», «сделай снимок модели».
|
||||
«что в этой сборке», «нарасти/измени деталь», «раскрась модель / выдели надпись цветом», «экспортируй STEP»,
|
||||
«сделай снимок модели».
|
||||
---
|
||||
|
||||
# kompas-3d — методика управления КОМПАС-3D через MCP
|
||||
@@ -23,6 +24,26 @@ MCP-сервер даёт **общие** операции КОМПАС (эски
|
||||
Любая задача «сделать что-то В КОМПАС» через MCP: создать/править деталь, эскизы и операции,
|
||||
импорт/экспорт обменных форматов, разбор сборки, измерения, снимки.
|
||||
|
||||
## Указатель: тип задачи → файл
|
||||
|
||||
Этот файл — ядро: применяется в любой задаче. Развёрнутый playbook под конкретный тип работы вынесен
|
||||
в `reference/*.md` — читай Read'ом ровно тот файл, что подошёл, остальные не трогай.
|
||||
|
||||
| Задача | Файл |
|
||||
|---|---|
|
||||
| Переменные, параметрическая модель | `reference/parametrization.md` |
|
||||
| Надпись, логотип, SVG, рельеф, выбор маршрута для внешнего контура | `reference/text-and-relief.md` |
|
||||
| Переиспользуемый чертёжный блок (*.frw) | `reference/fragments.md` |
|
||||
| Сборка с нуля (вставка, сопряжения, фиксация) | `reference/assembly-playbook.md` |
|
||||
| Чертёж по ГОСТ, виды, разрез, размеры | `reference/drawing-playbook.md` |
|
||||
| Разбор ЧУЖОЙ модели/сборки (импорт, STEP) | `reference/import-playbook.md` |
|
||||
| Исполнения (типоразмеры, зеркала в одном файле) | `reference/embodiments-playbook.md` |
|
||||
|
||||
Ни один файл не подошёл — вопрос, скорее всего, про механику КОНКРЕТНОГО инструмента, а не про
|
||||
порядок работы: туда — `help(topic="…")`/`help(query="…")` (см. ниже), а не в `reference/`.
|
||||
Не нашёлся и там — `Grep` по `reference/**` словами задачи: это и есть весь механизм поиска, ничего
|
||||
специального заводить не пришлось.
|
||||
|
||||
## Два правила прежде всего
|
||||
|
||||
**1. «Зрение» — структурное, не по картинке.** «Увидеть» деталь = **`describe_model`** — паспорт
|
||||
@@ -40,7 +61,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
скажет «Документ ТРЕБУЕТ ПЕРЕСТРОЕНИЯ» (`needsRebuild: true`); увидел — `rebuild` и повтори осмотр,
|
||||
выводов по непересчитанной модели не делай.
|
||||
|
||||
**2. Ответ мутирующей операции — это ТРИ проверки, читай все.** Любая операция может «пройти»
|
||||
**2. Ответ мутирующей операции — это НЕСКОЛЬКО проверок, читай все.** Любая операция может «пройти»
|
||||
(`Create()==true`), оставив деталь в ошибке, поэтому каждая мутирующая операция сама дописывает
|
||||
к ответу итог проверки построения и сводку состояния «Тел: N, объём V мм³»:
|
||||
|
||||
@@ -52,12 +73,30 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
- **«Тел: 2»** там, где ждёшь одно тело, — деталь распалась: касание объединением не считается
|
||||
(см. «Надписи»). Смотри на число ТЕЛ, а не граней: объединение сливает компланарные грани,
|
||||
и счётчик граней законно остаётся прежним.
|
||||
**Но обратное неверно: «Тел: 1» распад не опровергает.** Счётчик в сводке ОПАЗДЫВАЕТ. Замер
|
||||
(журнал операций кейса с хвостом по сечениям): `loft` построил второе тело и отчитался
|
||||
«Тел: 1», следом `pattern(kind=mirror)` — снова «Тел: 1», и только третья операция, `chamfer_edge`, напечатала
|
||||
«Тел: 2», хотя между ними ничего не создавалось. Три операции подряд шли по детали, объём
|
||||
которой считал пересечение дважды. Поэтому «Тел: 2» — тревога, которой верят сразу, а «Тел: 1» —
|
||||
не доказательство: там, где важно именно СРАСТАНИЕ (loft/sweep на грань, надпись, примитив
|
||||
впритык), проверяй `describe_model(sections="bodies")` — у каждого тела там свой габарит — и сверяй
|
||||
объём с прикидкой.
|
||||
- **Объём сверяй с прикидкой** «площадь контура × высота». Так ловятся молча не применившаяся
|
||||
тонкая стенка (прирост как у сплошного сечения), вычитание мимо цели и операция «не туда» —
|
||||
габарит и снимок этого не покажут.
|
||||
- **«⚠ Сверка с запросом: …»** — четвёртая, отдельная от первых трёх строка: сервер сравнил
|
||||
результат с ВХОДНЫМИ параметрами вызова. Сейчас это положение материала у `extrude(mode=boss)`
|
||||
и покрытие сечений у `loft(mode=boss)` (на базовых и смещённых плоскостях), убыль объёма у
|
||||
`extrude(mode=cut)`, а у `primitive` — объём против номинала по его же размерам. Сработала —
|
||||
построено не то, о чём просили, и в тексте сказано что именно. **Молчание успех НЕ доказывает**:
|
||||
сверка односторонняя и намеренно молчит там, где улика неоднозначна (прирост меньше
|
||||
запрошенного, материал целиком внутри габарита, эскиз выдавливания на грани, сечения лофта на
|
||||
наклонной грани или с одинаковыми именами). Размер-выражение сверке не мешает: и у `primitive`,
|
||||
и у `extrude` величина проверяется по уже вычисленному значению. Механика и границы —
|
||||
`help(topic="build-verification")`.
|
||||
|
||||
Отдельный `describe_model(sections=errors,bodies,mass)` после каждого шага не нужен. Он
|
||||
возвращается, когда авто-проверку выключили (`set_auto_validate(false)` на тяжёлой модели, где
|
||||
возвращается, когда авто-проверку выключили (`kompas_connect(autoValidate=false)` на тяжёлой модели, где
|
||||
проверка каждого шага тормозит): тогда `describe_model(sections=errors,bodies,mass)` вручную перед выдачей: одного
|
||||
`errors` мало — распад детали на два тела показывает только раздел `bodies`.
|
||||
|
||||
@@ -76,58 +115,12 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
намеренно не повторяется. Справочник описывает ЭТОТ сервер; справка по COM API КОМПАС — отдельная
|
||||
история и в работе через MCP не нужна.
|
||||
|
||||
## Инструменты: индекс групп
|
||||
## Инструменты: где искать каталог
|
||||
|
||||
Актуальный перечень с описаниями параметров отдаёт сам MCP-сервер — здесь только карта:
|
||||
|
||||
- *Система/документы:* `kompas_connect` (shared|private|attach), `kompas_set_visible`,
|
||||
`kompas_status`, `set_auto_validate`, `set_operation_log`; `document_create|open|save|close`,
|
||||
`document_active` (тип, путь, есть ли несохранённые изменения, «только чтение», материал детали),
|
||||
`document_list` (все открытые документы — им проверяют, что имя файла занято другим документом
|
||||
и что несохранённого не осталось), `set_part_info`, `set_part_material`.
|
||||
- *Эскиз:* `sketch_create` (основание: `plane`+`offset` | `faceIndex` | точка; геометрия — списком
|
||||
`entities` **или** файлом `entitiesFile`), `sketch_add`, `sketch_close`; `measure_text` — замер
|
||||
надписи без построения; `fragment_create` — тот же список примитивов, но в самостоятельный
|
||||
файл-фрагмент (*.frw); `fragment_place` — положить готовый фрагмент в чертёж.
|
||||
- *Формообразующие:* `primitive`, `extrude`, `revolve`, `fillet_edge`, `chamfer_edge`, `shell`,
|
||||
`rib`, `sweep`, `loft`, `draft`, `hole`, `pattern`, `mirror`, `feature_delete`, `rebuild`.
|
||||
- *Прямое редактирование (в т.ч. импортированная B-rep):* `move_face`, `split_solid_by_plane`,
|
||||
`move_body`, `boolean_union`.
|
||||
- *Переменные:* `set_variable`, `list_parameters`, `link_parameter`, `delete_variable`
|
||||
(сами переменные показывает `describe_model(sections=variables)`).
|
||||
- *Обмен:* `import_model` (3D: step, iges, sat, xt, stl, c3d, jt, obj + родные форматы чужих САПР),
|
||||
`import_drawing` (плоский .dxf/.dwg), `export_model` (`format=auto` по расширению: `.step` —
|
||||
точная геометрия в другую САПР, `.stl` — сетка в слайсер).
|
||||
- *Исполнения:* `embodiment` (`set|add|delete|rename`; `kind=embodiment|mirror|variant`) — несколько
|
||||
геометрий одной модели в одном файле; список с габаритом и массой каждого —
|
||||
`describe_model(sections=embodiments)`.
|
||||
- *Сборка:* `assembly_add_component` (положение + поворот `rx/ry/rz`, `embodiment` — какое исполнение
|
||||
источника вставлять), `assembly_add_mate` (стороной может быть грань ИЛИ вспомогательный объект
|
||||
`object1/object2`: плоскости и оси СК компонента, а без `componentIndex` — самой сборки)
|
||||
(семь типов, `orientation`), `assembly_fix_component`, `assembly_delete`,
|
||||
`assembly_check_interference` (не налезли ли детали друг на друга — больше это не видно нигде),
|
||||
`assembly_transform_point` (`to=world|local` — точка между ЛСК компонента и СК сборки).
|
||||
- *2D-чертёж:* `drawing_create_standard_views` (`views[]`, `mainOrientation`, `hiddenLines`),
|
||||
`drawing_add_view` / `drawing_move_view` / `drawing_delete_view` / `drawing_get_view_info`
|
||||
(компоновка листа и паспорт вида), `drawing_add_section_view` (РАЗРЕЗ или СЕЧЕНИЕ: линия разреза
|
||||
на базовом виде и производный вид по ней — одним вызовом), `drawing_add_sheet`,
|
||||
`drawing_set_sheet_format`,
|
||||
`drawing_fill_title_block`,
|
||||
`drawing_add_linear|diametral|radial|angular_dimension` (у всех — `tolerance`/`prefix`/`suffix`/
|
||||
`textOverride`; у Ø и R — ещё `objectKind`/`objectIndex`, прямой адрес окружности или дуги),
|
||||
`drawing_add_axis`, `drawing_add_rough|text|leader`,
|
||||
`drawing_set_unspecified_rough`, `drawing_set_technical_requirements`, `drawing_delete_object`,
|
||||
`drawing_move_object` (сдвинуть поставленное), `drawing_project_point` (точка модели → координаты
|
||||
вида), `drawing_export_image` (посмотреть
|
||||
глазами). Обратное чтение — `drawing_get_title_block` и `drawing_get_technical_requirements`:
|
||||
технические требования ПЕРЕЗАПИСЫВАЮТСЯ целиком, поэтому правку одного пункта начинают с чтения
|
||||
текущего текста. Методика — §«Чертёж».
|
||||
- *Осмотр:* `describe_model` (разделы `box|mass|bodies|topology|tree|variables|errors|components|mates` —
|
||||
габарит, МЦХ, тела, топология, дерево построения, переменные, операции в ошибке, состав сборки,
|
||||
сопряжения), `measure`, `model_snapshot`; адресация объектов — `list_faces` / `list_edges`.
|
||||
Для 2D-документов — свой: `list_drawing_objects` (что лежит в чертеже/фрагменте).
|
||||
|
||||
Три сквозных свойства контракта: **размерный параметр принимает число ИЛИ выражение** (имя
|
||||
Полный перечень инструментов с параметрами — `tools/list` самого MCP-сервера (единый источник
|
||||
правды, держать вторую копию здесь не нужно). Что известно про
|
||||
КОНКРЕТНЫЙ инструмент — `help(tool="extrude")`. Три сквозных свойства контракта, которые полезно
|
||||
держать в голове, а не искать заново на каждом инструменте: **размерный параметр принимает число ИЛИ выражение** (имя
|
||||
переменной/формулу — параметр сразу становится ведомым); **объект выбирается индексом** (надёжно)
|
||||
или точкой (запасной путь — если выбирал точкой, ответ подскажет, что выбралось); **списковые
|
||||
параметры** (`entities[]`, `edgeIndices[]`, `points[]`, `faceIndices[]`, `variables[]`, `links[]`) —
|
||||
@@ -138,6 +131,14 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
остаётся — повторяй вызов с оставшимися, а не с начала. Если инструмента под задачу нет — собирай
|
||||
результат из имеющихся общих операций.
|
||||
|
||||
**Оговорка для больших групп рёбер в `fillet_edge`/`chamfer_edge`.** «Один вызов на весь пакет»
|
||||
экономит вызовы, но у катета/радиуса есть рабочий диапазон, заданный ВСЕЙ группой рёбер разом, а
|
||||
не отдельным ребром (измерено: один и тот же контур строится с меньшим катетом и отказывает с
|
||||
большим). Параметрическая модель может пройти это на одном значении переменной и отказать на
|
||||
другом — большая группа сама по себе фактор хрупкости при последующей правке размеров. Если пакет
|
||||
на 15+ рёбер отказывает без диагноза по длине, разбейте его на 2–3 группы — сервер сам подскажет
|
||||
это в тексте отказа (`help(topic="edge-groups")`).
|
||||
|
||||
## Два пути формообразования — выбирай по форме, а не по привычке
|
||||
|
||||
«Эскиз → выдавливание» — не единственный способ. `primitive` строит тело сразу по размерам, и это
|
||||
@@ -148,8 +149,12 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
| Плита, брусок, бобышка, штифт, цилиндрическая стойка | `primitive(kind=block\|cylinder)` — один вызов вместо «эскиз + выдавливание» |
|
||||
| Прямоугольный карман, паз, срез угла | `primitive(..., result=subtract)` — вычитание тела вместо `extrude(mode=cut)` по эскизу |
|
||||
| Скруглённые углы призмы | `primitive` + `fillet_edge` по рёбрам (скругление после, а не дуги в эскизе) |
|
||||
| Текст, кривые, произвольный контур, переменное сечение | ТОЛЬКО эскиз: `sketch_create(entities=[…])` + `extrude`/`revolve`/`loft`/`sweep` |
|
||||
| Текст, кривые, произвольный контур | ТОЛЬКО эскиз: `sketch_create(entities=[…])` + `extrude`/`revolve` |
|
||||
| Переменное сечение: хвост, гребень, переход круга в квадрат | `loft` по сечениям на смещённых плоскостях (`mode=boss` приклеивает к телу) |
|
||||
| Труба, поручень, кант по кривой | `sweep(profileSketchId, pathSketchId)` — профиль и траектория на разных плоскостях |
|
||||
| Тонкая стенка, ободок по контуру | эскиз + `extrude(thinThickness, thinSide)` |
|
||||
| Наклонная полка, скос, элемент под углом | `sketch_create(plane, planeAngle, planeAxis)` или `planePoints` (три вершины) + `extrude`; сторону берёт нормаль из ответа — `help(topic="auxiliary-planes")` |
|
||||
| Резьба на валу или в отверстии (M10, M8×1) | `thread` на цилиндрической грани — условное изображение, тело не режет; в отверстии сначала `hole` под сверло (M10 → Ø8.5), потом `thread` — `help(topic="threads")` |
|
||||
|
||||
Их **сочетают в одной детали**: корпусные объёмы — примитивами, сложные контуры — эскизами.
|
||||
|
||||
@@ -170,14 +175,32 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
координат — одна операция на все; точки без ребра ошибка перечислит разом.
|
||||
- **Скругление не построится там, где ребро «съедено» соседним элементом** (угол плашки под каймой
|
||||
букв). Это нормальный ответ геометрии, а не ошибка вызова: проверь снимком, виден ли угол снаружи.
|
||||
- **Фаска на почти касательном стыке может ДОСТРОИТЬ объём, а не срезать.** Замер: `chamfer_edge`
|
||||
0.3 по кромке, где поверхность лофта сходит в плоскость почти по касательной, — «построение
|
||||
чистое», а объём ВЫРОС на 2.2 мм³. На выпуклом ребре фаска обязана объём УМЕНЬШАТЬ (на вогнутом
|
||||
легитимно добавляет); сверяй ЗНАК приращения в сводке ответа со своим ожиданием — вырос без
|
||||
причины, значит фаска выродилась в достройку: убери её `feature_delete`, пологому стыку она
|
||||
и не нужна.
|
||||
- **`result=new` даёт ОТДЕЛЬНОЕ тело**, `subtract` мимо цели сервер ловит сам — и то и другое
|
||||
видно по сводке «Тел/объём» в ответе; при распаде зови `boolean_union`.
|
||||
видно по сводке «Тел/объём» в ответе; при распаде зови `boolean`.
|
||||
- **Сужающуюся или изогнутую форму не набирай лесенкой из примитивов.** `primitive` не умеет
|
||||
поворота, и «хвост» из десятка блоков со ступеньками — это обход отсутствующего инструмента,
|
||||
а не решение: он и печатается хуже, и правится только целиком. Бери `loft` по 4–6 сечениям на
|
||||
смещённых плоскостях — параметричность не теряется, `offset` плоскости принимает выражение.
|
||||
**`loft` может отказать молча, и отказ зависит от ПРОЛЁТА, а не от одного сечения** — поиск
|
||||
виновника перебором пар не работает, ломается СОЧЕТАНИЕ «сечение-выброс + длина набора»; механика
|
||||
и порядок поиска — `help(topic="loft-and-sweep")`.
|
||||
- **`loft(mode=boss)` прирастает перекрытием, а не касанием.** Первое сечение ставь на плоскость
|
||||
ВНУТРИ уже построенного тела (смещение на 1–2 мм вглубь), а не на его грань: касание объединением
|
||||
не считается — на грани получишь ВТОРОЕ тело вместо приросшего. **Проверять это сводкой «Тел: 1»
|
||||
НЕЛЬЗЯ** — именно здесь она и соврала (см. правило 2): считай тела
|
||||
`describe_model(sections="bodies")`, там у каждого свой габарит, и сверь объём с прикидкой.
|
||||
|
||||
## Базовый цикл (эскиз → операция → осмотр)
|
||||
|
||||
Опорный сценарий построения, проверен end-to-end:
|
||||
|
||||
1. `kompas_connect` (+ `kompas_set_visible true`). **Работаешь не один — бери свой экземпляр:**
|
||||
1. `kompas_connect` (+ `visible=true`). **Работаешь не один — бери свой экземпляр:**
|
||||
`kompas_connect(instance="private")` (см. «Когда КОМПАС общий»).
|
||||
2. `document_create(type="part", name="…")` — наименование даём сразу, здесь оно ничего не стоит.
|
||||
3. **Запиши замысел переменными** до первого эскиза (см. «Параметризация») и связывай каждый
|
||||
@@ -186,7 +209,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
5. `extrude` / `revolve` → прочитай итог проверки и сводку прямо в ответе (правило 2).
|
||||
6. Осмотр — структурно: `describe_model` (нужен кусок — `sections="box,mass"`).
|
||||
7. Итерация «на грани»: `list_faces` → `sketch_create(faceIndex=N, entities=[…])` → операция.
|
||||
8. **Задай материал, если смотришь на массу** — `set_part_material`: у нового документа стоит
|
||||
8. **Задай материал, если смотришь на массу** — `set_part_info(material, density)`: у нового документа стоит
|
||||
сталь 7.86, и МЦХ печатной детали завышена вшестеро; плотности ходовых материалов перечислены
|
||||
в описании инструмента.
|
||||
9. **Проверь, что деталь названа** (шаг 2 или `set_part_info`) — безликая «Деталь» уедет в штамп
|
||||
@@ -203,29 +226,37 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
пересборки. Набор переменных — это план построения числами и паспорт, по которому человек поймёт
|
||||
модель, не разбирая дерево.
|
||||
|
||||
- **Заводи переменной то, что было РЕШЕНИЕМ**: габариты из ТЗ, толщины, зазоры, отступы, кегли,
|
||||
радиусы. Выводимое задавай формулой (`plate_L = badge_L - 2*edge_gap`) — правка ведущего размера
|
||||
пересчитает зависимые сама. Позиции, подобранные замером, оставляй числами: связь — обещание,
|
||||
что правка переменной даст осмысленный результат, а на позиционных числах она чаще ломает деталь.
|
||||
- **Размер передавай выражением прямо в операцию** (`extrude(depth="badge_T")`) — параметр сразу
|
||||
становится ведомым, внутреннее имя параметра («Расстояние 1») знать не нужно. Переменная должна
|
||||
существовать ДО операции — потому паспорт и заводят первым. Задним числом и для параметров,
|
||||
которых нет среди аргументов инструмента (углы уклона, второе направление), — `link_parameter`.
|
||||
- **Промахи сервер ловит сам:** ссылка на несуществующее имя — отказ с перечнем виновных (и в
|
||||
выражениях операций, и в `set_variable`; регистр значим), функции в формулах — предупреждение
|
||||
(тригонометрия в радианах, разделитель аргументов «;», непонятая запись = молчаливый 0).
|
||||
Твоя часть — **сверить вычисленные значения из ответа со своей прикидкой**.
|
||||
- **`note` обязателен** и пишется по-русски, со смыслом и единицей; `(ТЗ)` метит числа,
|
||||
зафиксированные пользователем. **Что замерил — верни в переменную** (фактический кегль, прирост
|
||||
каймы), иначе паспорт разойдётся с моделью и станет дезинформацией. Переосмысливать можно всё,
|
||||
кроме помеченного `(ТЗ)`.
|
||||
- **После связывания правка паспорта перестраивает деталь** (проверено: `set_variable(badge_T=4)` →
|
||||
габарит по Z 3.00 → 4.00, объём 5154.5 → 5861.5 мм³). Это и есть параметрическая модель,
|
||||
а не комментарий к ней. **До связывания — не перестраивает**, и `set_variable` говорит об этом
|
||||
прямо: «⚠ НИЧЕГО НЕ ВЕДЁТ». Такой ответ — не успех: число поменялось, деталь нет.
|
||||
- **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт» — это либо забытая
|
||||
связь, либо мусор; разбери оба. `delete_variable(unused=true)` — только ПОСЛЕ `link_parameter`
|
||||
на всё, что должно вести геометрию: вычистка не отличает мусор от несвязанного размера из ТЗ.
|
||||
- **Заводи переменной то, что было РЕШЕНИЕМ** (габариты из ТЗ, толщины, зазоры), позиции, подобранные
|
||||
замером, оставляй числами; **размер передавай выражением прямо в операцию**
|
||||
(`extrude(depth="badge_T")`) — переменная должна существовать ДО операции.
|
||||
- **После связывания правка паспорта перестраивает деталь; до связывания — нет**, и `set_variable`
|
||||
прямо говорит «⚠ НИЧЕГО НЕ ВЕДЁТ» в этом случае — не успех, хоть число и поменялось.
|
||||
- **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт»;
|
||||
`delete_variable(unused=true)` не трогает справочные (`information`) и внешние.
|
||||
- **Проверь крайние значения переменных ДО прогона.** Размер, зависящий от модуля или шага, но
|
||||
заданный числом, ломает модель на соседнем значении (обод Ø178 при m=4 оказывается шире
|
||||
вершин Ø172 — профиль самопересекается). Веди такие размеры от той же переменной.
|
||||
- **Галтель, скругление угла профиля** — примитив `{type:"fillet", between:[i, j], radius}` на
|
||||
острый угол двух отрезков или дуг: точное сопряжение находит решатель КОМПАС, считать точки
|
||||
касания не нужно (`help(topic="sketch-entities")`). Радиус ведёт переменная — `radius` на номер
|
||||
`fillet` в `dimensions`. Если две галтели по данным сходятся в одну (центр уходит за ось
|
||||
симметрии, дуги дна между ними нет) — один `fillet` прямо между двумя боковыми дугами.
|
||||
- **Паз со сбегом по дуге** (выход дисковой фрезы): прорежь паз `extrude(cut)` с перебегом за
|
||||
место сбега, затем верни лишнее `revolve(boss)` профиля, ограниченного дугой сбега, вокруг оси
|
||||
вала; либо `revolve(cut)` сечения паза вокруг оси фрезы. У `extrude` нет переменного дна.
|
||||
- **Фаски и скругления на кромках зубчатого венца — ДО нарезки зубьев:** одно круговое ребро
|
||||
заготовки вращения вместо десятков рёбер после массива (иначе их перечисляют индексами).
|
||||
- **Профиль вала вдоль Z рисуется на XOZ вниз от оси X:** точка (r; −z) — локальная v эскиза
|
||||
смотрит в −Z (`help(topic="sketch-dimensions")`). Адресуя потом рёбра и грани точками, бери
|
||||
мировые z ≥ 0, а не координаты эскиза.
|
||||
- **Формулы:** тригонометрия в РАДИАНАХ, константы π нет — заведи `dg = 0.017453292519943295` и
|
||||
пиши `cos(alpha*dg)`; в формуле регистр имени значим, а `spl_d` и `spl_D` — одна переменная.
|
||||
- **Связь — в эскизе, а не в калькуляторе** (точную начальную точку дай выражением прямо в координате): точка на кривой (`coincident`, `to.point: "curve"`),
|
||||
касание (`tangent`), расстояние до прямой (`distance`), угол к оси (`angle` с `to.ref`), опоры
|
||||
вне профиля — `construction: true`. Что выражено ограничением, переживает смену переменной.
|
||||
|
||||
Полная методика — обязательные поля (`note`), как сервер ловит промахи в формулах, справочные
|
||||
переменные `(ТЗ)` и порядок уборки — [reference/parametrization.md](reference/parametrization.md).
|
||||
|
||||
## Надписи, логотипы и рельеф
|
||||
|
||||
@@ -247,301 +278,98 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
- **Надпись и плашка обязаны ПЕРЕКРЫВАТЬСЯ** — по размерам чертежа блоки обычно только касаются,
|
||||
а касание объединением не считается. Приём: кайму/полосу плашки сделать выше самой плашки на
|
||||
1–1.5 мм с той стороны, где стоит надпись. Распад видно по «Тел: 2» в ответе операции — не тяни
|
||||
проверку до конца построения.
|
||||
проверку до конца построения. Молчание сводки распад не опровергает (счётчик опаздывает, п. 2):
|
||||
убедиться, что срослось, можно только `describe_model(sections="bodies")`.
|
||||
- **Рельеф = разница глубин от одной плоскости** (основание 2 мм + буквы 3 мм = выступ 1 мм);
|
||||
не строй буквы «на грани основания» — из одного эскиза на базовой плоскости получается и то и
|
||||
другое, и рельеф не зависит от порядка операций.
|
||||
- **Надпись читается только с той стороны, куда смотрит нормаль плоскости эскиза** — XOY → +Z,
|
||||
XOZ → +Y, **YOZ → −X**. Гравировка по эскизу на YOZ, положенная на грань с бОльшим X, выходит
|
||||
ЗЕРКАЛЬНОЙ, и `angle` этого не исправляет: он вращает, а не отражает (замер — цифра на щеке
|
||||
X=20.4 зеркальна при любом угле, тот же эскиз на X=0 встаёт верно). Выбирайте грань по нормали,
|
||||
а поворотом задавайте только, куда смотрит верх глифа. Проверять — снимком С ТОЙ СТОРОНЫ, где
|
||||
надпись будет видна: `model_snapshot(view=left)` для грани X=0, `right` для X=max.
|
||||
- **Шрифт должен быть установлен в системе** — неизвестное имя КОМПАС молча подменяет; сервер
|
||||
предупреждает об этом в ответе `sketch_create`/`measure_text` — не игнорируй.
|
||||
|
||||
**Логотип, которого нет в шрифте, приходит готовым вектором (SVG).** Переводи его в примитивы
|
||||
эскиза сам — `line` и `arc3points`, а не ломаной: контур из сотен звеньев даёт деталь в сотни
|
||||
граней, и фаска по такому низу не строится. Кубические Безье режь пополам, пока дуга по трём
|
||||
точкам не ляжет в допуск. Четыре вещи, каждая из которых стоила захода:
|
||||
**Логотип (SVG) и выбор маршрута для внешнего контура (вычисляемый / срисованный / CAD-файл) —
|
||||
в [reference/text-and-relief.md](reference/text-and-relief.md).** Там же — точная подгонка (кегль
|
||||
под заданную ширину, ступени `widthFactor`/`height`, приросты каймы на острых терминалах, разрядка
|
||||
пробелами, кайма вокруг прямоугольной плашки) и отделка рельефа (скругления/фаски на сотнях рёбер).
|
||||
Прочитай его, как только контур не сводится к простому вычисляемому эскизу.
|
||||
|
||||
- **Ось Y в SVG смотрит вниз** — без инверсии контур встаёт вверх ногами, и это видно только на снимке.
|
||||
- **Дуги задавай тремя точками** (`arc3points`): концы заданы явно, соседние примитивы стыкуются
|
||||
точно. Перед постройкой проверь цепочку — конец примитива против начала следующего, разрыв 0.
|
||||
- **Чисти мелочь под масштаб детали — параметром `minSegment`.** SVG рисуют в своём габарите (сотня
|
||||
условных единиц), и его скругления после масштабирования превращаются в дуги по 0.02–0.5 мм;
|
||||
замыкающий `z` часто даёт ещё и сегмент нулевой длины. `chamfer_edge` по такому набору отвечает
|
||||
«катет больше длины N из M рёбер» — и это правда. Передай `sketch_create(minSegment=катет)` (тот же
|
||||
параметр есть у `sketch_update` и `fragment_create`), и та же фаска пройдёт с первой попытки;
|
||||
отчёт о выброшенном читай, а не пролистывай — `help(topic="contour-cleanup")`.
|
||||
Фрагмент (*.frw, самостоятельный файл переиспользуемого контура/чертежа) —
|
||||
[reference/fragments.md](reference/fragments.md).
|
||||
|
||||
**Порядок для фаски по контуру логотипа — только такой, и он неочевиден:**
|
||||
## Раскраска: умеренно и по смыслу
|
||||
|
||||
1. **чистка** порогом ≈ будущего катета (`minSegment`);
|
||||
2. **замер ЧИЩЕНОГО силуэта** — `sketch_measure_thickness(entitiesFile, minSegment=тот же порог)`;
|
||||
3. **катет по узкому месту** чищеного силуэта: `c ≤ (узкое_место − 2·w)/2`, где `w` — ширина нити.
|
||||
Цвет — последний шаг, после геометрии: `set_appearance` её не трогает и в дереве узлов не
|
||||
плодит. Задача раскраски — чтобы модель читалась с первого взгляда, а не чтобы она была пёстрой.
|
||||
|
||||
Менять шаги местами нельзя: **чистка СУЖАЕТ узкое место**. Она заменяет скругление острым углом —
|
||||
в выпуклом углу это добавляет материал (габарит подрастает), а в вогнутом срезает его, и именно
|
||||
вогнутые углы образуют перемычки между штрихами. Замер обводки логотипа шириной 105 мм:
|
||||
узкое место 1.98 → 1.82 мм, порог распада лицевой грани 0.99 → 0.91. Катет, подобранный по
|
||||
нечищеному контуру, после чистки перестаёт проходить свой же критерий.
|
||||
- **Одна основа, один-два акцента.** Деталь целиком — спокойный нейтральный цвет
|
||||
(`target="part"`), акцент — тому, что должно бросаться в глаза: надпись, логотип, кнопка,
|
||||
посадочная поверхность. Три и больше акцентов уже шумят.
|
||||
- **Надпись и логотип красятся ОПЕРАЦИЕЙ**, которая их выдавила
|
||||
(`target="feature", ids=["op_…"]`): так окрашиваются и лицевые грани, и стенки букв. Хендл
|
||||
берётся из ответа `extrude`; если хендлов уже нет — индекс узла из
|
||||
`describe_model(sections=tree)`. Красить только верх букв — `target="face"` пакетом индексов.
|
||||
- **Порядок: сначала общее, потом частное.** Своё перекрывает унаследованное в порядке
|
||||
грань > операция > тело > деталь, так что поздний цвет детали акценты не затрёт.
|
||||
- **Проба и откат**: объект, который до пробы наследовал вид, возвращают `reset=true`, а не
|
||||
обратным значением — запись даже одной `opacity` закрепляет за ним и цвет («⚠ Цвет закреплён» в
|
||||
ответе). Если вид был свой, откат — прежние значения из «было → стало» ответа.
|
||||
- **Сборка — компонент на свой цвет**, близкие по назначению — близкими оттенками; корпус,
|
||||
сквозь который надо видеть внутренности, — `opacity` 0.3–0.5. Цвет компонента живёт в сборке,
|
||||
файл детали не меняется — но он перекрывает ВСЕ акценты детали (надпись станет цвета
|
||||
компонента). Нужны акценты — оставь компоненту наследуемый цвет. Грань или тело ВНУТРИ
|
||||
компонента из сборки не красятся: акценты, общие для всех экземпляров, задают в файле детали.
|
||||
- **Передача дальше**: STEP несёт цвета и прозрачность, но не текстуры и вырезы; STL не несёт
|
||||
оформления вовсе. Ответ `export_model` перечисляет попавшие цвета и называет, что потеряно.
|
||||
- **Отделка по материалу**: металл — `finish="metal"` (`silver`, `gold`), пластик — `satin` или
|
||||
`matte`, `glossy` — умолчание КОМПАС.
|
||||
- **Текстура — там, где она что-то говорит**: накатка на рукоятке (`texture="diamond knurl"`,
|
||||
`textureSize` 3–10 мм — при умолчании 100 узор не виден), дерево, шлифованный металл, сварной
|
||||
шов. Размер — плитка в мм модели; проверка снимком (текстуры он рисует). Текстура операции
|
||||
ложится на ВСЕ её грани, торец рукоятки тоже — накатку как у эталона ASCON кладут на боковую
|
||||
грань (`target="face"`). Своя картинка — это ссылка на файл: модель её не хранит, предпочитай
|
||||
библиотеку КОМПАС.
|
||||
- **Перфорация и сетка — вырезом, а не геометрией**, если отверстия нужны только для вида:
|
||||
`cutout="hexagon"` (или `expanded metal` вместе с одноимённой текстурой) делает окна сквозными
|
||||
на снимке, не трогая массу и топологию. Нужны настоящие отверстия под крепёж или DFM — это
|
||||
`hole`/`pattern`, вырез их не заменяет. Рисунок «не тем боком» — `textureAngle`, сдвиг —
|
||||
`textureOffset` (оба вместе с повтором имён `texture` и `cutout` — повернётся только то, что
|
||||
названо в вызове; поворот 0…180°). Смена рисунка плитку и раскладку сохраняет.
|
||||
- **Проверка — глазами**: `model_snapshot(view="iso")` после раскраски; что окрашено на самом
|
||||
деле — `describe_model(sections=appearance)`. Прозрачность снимок не рисует — её видно только
|
||||
в разделе `appearance`.
|
||||
|
||||
- **Ширину штриха и узкое место меряй инструментом, а не глазом** — `sketch_measure_thickness`
|
||||
ничего не строит и документа не требует, поэтому зовётся ДО эскиза
|
||||
(`help(topic="silhouette-thickness")`). От этих чисел зависит, останется ли что-то от рисунка
|
||||
после фаски и напечатается ли он вообще; шаг растра в ответе — точность округления катета.
|
||||
|
||||
Контур, который переживёт конкретную деталь (логотип, шаблон, профиль), клади во фрагмент —
|
||||
`fragment_create(path, entities)` тем же списком примитивов. Активный документ он не подменяет,
|
||||
поэтому фрагмент можно снять посреди построения детали; габарит в ответе снят с самого документа —
|
||||
сверяй его с задуманным.
|
||||
|
||||
**Точная подгонка и отделка — в [reference/text-and-relief.md](reference/text-and-relief.md);
|
||||
прочитай его, как только доходишь до точной компоновки надписи или отделки рельефа:** подбор кегля
|
||||
под заданную ширину за одну пробу, ступени `widthFactor`/`height`, приросты каймы на острых
|
||||
терминалах (t/sin(θ/2)) и её роль в стыковке блоков, разрядка пробелами, кайма вокруг прямоугольной
|
||||
плашки, карманы `primitive(subtract)` рядом с буквами, скругления и фаски рельефа на сотнях рёбер.
|
||||
|
||||
## Внешний контур: не диктуй координаты, если фигуру нельзя описать формулой
|
||||
|
||||
Три маршрута, и выбор между ними механический — не по вкусу, а по происхождению геометрии.
|
||||
|
||||
| Откуда фигура | Чем строить |
|
||||
|---|---|
|
||||
| **Вычисляется**: пластины, рёбра, сетка отверстий | `sketch_create(entities[])` — прямо в вызове, размеры вяжи переменными |
|
||||
| **Срисована**: логотип, шаблон, кулачок, профиль | внешний вектор → JSON → `sketch_create(entitiesFile=…)` |
|
||||
| **Пришла в CAD-формате**: файл от смежника | `import_drawing` (.dxf/.dwg) → фрагмент → `fragment_place` |
|
||||
|
||||
**Обводка занимает сотни примитивов, и переписывать их в тело вызова незачем.** У `sketch_create`,
|
||||
`sketch_add` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`;
|
||||
сервер читает файл сам. Замер на эмблеме Volvo: SVG в 1.5 КБ даёт 96 примитивов (50 отрезков +
|
||||
46 дуг) и 9.5 КБ JSON; через `entitiesFile` это один вызов на одну строку аргументов, а эскиз
|
||||
строится за один заход. Оба параметра можно задать вместе — сначала `entities`, следом файл:
|
||||
так к готовому контуру дописывают рамку или ось, не трогая файл.
|
||||
|
||||
Что проверить **до** постройки, а не после: габарит в ответе (`fragment_create` печатает
|
||||
фактический — сверь с задуманным) и вложенные контуры. Правил заливки у эскиза КОМПАС нет: любой
|
||||
вложенный контур он режет как отверстие, даже там, где вектор заливал материал. Конвертер такие
|
||||
места называет заранее — на них смотри до выдавливания, иначе дыры обнаружатся на снимке.
|
||||
|
||||
## Фрагмент — переиспользуемый чертёж, а не сечение
|
||||
|
||||
Эскиз живёт внутри дерева построения и вне его не существует; фрагмент (*.frw) — самостоятельный
|
||||
файл, который переживает деталь. `fragment_create` его пишет, `fragment_place` кладёт в активный
|
||||
чертёж или другой фрагмент, а `mode` решает, чем он там станет — и это разные объекты, а не
|
||||
оттенки одного:
|
||||
|
||||
- **`reference`** — вставка-ссылка: содержимым владеет файл, правка файла меняет все документы, куда
|
||||
он вставлен. Ради этого фрагменты и заводят: одна заготовка на десять чертежей.
|
||||
- **`copy`** — копия внутри документа, живёт своей жизнью; файл потом можно удалить.
|
||||
- **`local`** — вставка, переиспользуемая только внутри этого документа.
|
||||
- **`explode`** — россыпь обычных примитивов: правится по одному, но связи с файлом уже нет.
|
||||
|
||||
`angle` (градусы), `scale` и `mirror` задают размещение; зеркалить можно только вставку — у россыпи
|
||||
отражать нечего. **Зеркало отражает относительно вертикали через точку вставки**, поэтому контур
|
||||
уходит в другую сторону от неё: вставка в x=220 после `mirror` занимает 160…220, а не 220…280.
|
||||
|
||||
Проверять результат — `list_drawing_objects`: он показывает состав по типам, габарит и все вставки
|
||||
с их файлами. Вставка, чей файл потерялся, рисуется пустым местом — в списке она помечена
|
||||
недействительной, и это единственный способ отличить её от удавшейся, не глядя на экран.
|
||||
Механизм, имена цветов и измеренные факты — `help(topic="appearance")`.
|
||||
|
||||
## Сборка: собрать своё
|
||||
|
||||
Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.**
|
||||
Разбор чужой сборки — следующий раздел, здесь про сборку с нуля.
|
||||
|
||||
1. **Детали сначала сохрани в файлы.** Компонент вставляется ссылкой на `.m3d`/`.a3d`, поэтому
|
||||
несохранённую деталь вставить нельзя.
|
||||
2. **`document_create assembly` → `assembly_add_component(filePath, x, y, z, rx, ry, rz)`.** Углы — в
|
||||
градусах, вокруг СОБСТВЕННЫХ осей компонента и по очереди X→Y→Z: второй угол считается уже от
|
||||
повёрнутого положения. Пока задан один угол, разницы с мировыми осями нет.
|
||||
3. **Зафиксируй базовую деталь СРАЗУ: `assembly_fix_component(componentIndex=0, fixedState=true)`.** КОМПАС не закрепляет
|
||||
никого сам, включая первый компонент, и решатель двигает того, кого сочтёт нужным — в том числе
|
||||
основание, вокруг которого ты собираешь всё остальное. Это самая частая причина «сопряжение
|
||||
верное, а сборка расползлась».
|
||||
4. **Сопрягай:** `assembly_add_mate(mateType, …)` — семь типов, адресация гранью и смысл
|
||||
`orientation` в `help(topic="assembly-mates")`. Что решаешь ты, а не справочник:
|
||||
- **Грань адресуй индексом, а не координатами:** `list_faces(component=N)` → пара
|
||||
`faceIndex`+`componentIndex`. Точки на бумаге считать не нужно, и сервер сам проверит, что
|
||||
грань принадлежит этому компоненту.
|
||||
- **Сторону зазора у `distance` задаёт ВЫБОР ПАРЫ ГРАНЕЙ, и от стартового положения она не
|
||||
зависит.** «Closest» — не «ближайшее»: при сонаправленных нормалях объект 1 садится со стороны
|
||||
−n относительно объекта 2 (замерено двойным прогоном). Практическое правило: бери пару граней,
|
||||
которые смотрят ДРУГ НА ДРУГА. Вышло зеркально — меняй грань, а не `orientation`.
|
||||
- **Первое сопряжение вешай на зафиксированную деталь.** Пока в цепочке нет ни одного
|
||||
закреплённого звена, решатель волен двигать любое; связка «каждый новый компонент — к уже
|
||||
стоящему на месте» разваливается вдвое реже, чем связка «все ко всем».
|
||||
5. **`rebuild`,** если авто-валидация написала «ℹ Требуется перестроение». Это НЕ ошибка построения:
|
||||
так помечает себя свежий компонент или только что наложенная связь. Бросать работу здесь не надо
|
||||
— правило «не продолжай при ⚠» касается строки со знаком ⚠, а не этой.
|
||||
**Исключение из правила «⚠ = стоп».** После КАЖДОГО сопряжения авто-валидация пишет
|
||||
«⚠ N операц. в ошибке: „Сопряжения“ (код 0: ошибки нет)». Это то же «требуется перестроение»,
|
||||
только под знаком ⚠: код 0 и имя операции «Сопряжения» означают, что ломаться нечему. Делай
|
||||
`rebuild` и иди дальше. Настоящая беда со связью видна не здесь, а в
|
||||
`describe_model(sections=mates)` — по пометке `valid:false`.
|
||||
6. **Проверь:**
|
||||
- `describe_model(sections=components)` — origin, поворот ЧИСЛАМИ (`rx/ry/rz` в градусах, та же
|
||||
семантика, что у вставки) и «зафиксирован/свободен» у каждого: этим и видно, КОГО и НА СКОЛЬКО
|
||||
подвинул решатель;
|
||||
- `describe_model(sections=mates)` — что с чем связано, с каким значением и не выродилось ли.
|
||||
Это ключевой детектор: `assembly_add_mate` может ответить успехом, а связь окажется
|
||||
вырожденной;
|
||||
- `measure(kind1=face, index1=…, componentIndex1=…, kind2=face, index2=…, componentIndex2=…)` —
|
||||
зазор между деталями напрямую, без арифметики по габаритам;
|
||||
- `assembly_check_interference(componentIndex1, componentIndex2)` — **не налезли ли детали друг
|
||||
на друга.** Проверяй все пары, которые должны идти впритирку.
|
||||
|
||||
**Неудачную связь не нужно пересобирать с нуля:** `assembly_delete(target="mate"|"component", index)`
|
||||
снимает сопряжение или компонент вместе с опирающимися на него связями. Индексы после удаления
|
||||
сдвигаются — иди от больших к меньшим и перечитывай `describe_model(sections=mates)`.
|
||||
|
||||
**Пересечение деталей не видно НИГДЕ, кроме `assembly_check_interference`.** Сборка складывается из
|
||||
готовых тел, и КОМПАС их не вычитает: две детали могут занимать общий объём, а сопряжения при этом
|
||||
останутся `valid`, раздел `errors` — пустым, объём экспорта — простой суммой компонентов. `measure`
|
||||
тоже не спасает: нулевой зазор одинаково означает и касание, и взаимопроникновение. Проверяй все
|
||||
пары, которые должны идти впритирку.
|
||||
|
||||
**«Тела: 0» в сборке означает не «пусто», а «спрошено не то»:** тела принадлежат компонентам
|
||||
(`describe_model(component=N, …)`), а `box` и `mass` без `component` честно дают габарит и МЦХ сборки
|
||||
целиком. Про разные системы координат внутри паспорта компонента —
|
||||
`help(topic="model-inspection")`; про локальные координаты граней и `pointOnFace` —
|
||||
`help(topic="face-addressing")`.
|
||||
Сборка с нуля целиком, с адресацией граней, семью типами сопряжений и порядком проверки —
|
||||
[reference/assembly-playbook.md](reference/assembly-playbook.md). Разбор чужой сборки (пришедшей
|
||||
STEP/импортом) — следующий раздел.
|
||||
|
||||
## Чертёж: оформить деталь по ГОСТ
|
||||
|
||||
Чертёж строится не так, как деталь: **авто-валидации здесь нет**. Правило трёх проверок из §«Базовый
|
||||
цикл» в 2D не работает — операция не отчитывается «построилось верно», потому что верность тут не
|
||||
про геометрию, а про место на листе. Проверять приходится самому, и способ ровно один: посмотреть.
|
||||
|
||||
**Порядок, который окупается:**
|
||||
|
||||
1. **Деталь строится в чертёжной ориентации.** Набор видов задаётся ОТ модели: `mainOrientation`
|
||||
выбирает, какую ориентацию модели показывает главный вид, но саму ориентацию модели он не
|
||||
вращает. Если самая информативная проекция детали — не одна из шести стандартных, чертежа по
|
||||
ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость
|
||||
с наибольшей информацией.
|
||||
2. **`drawing_set_sheet_format`** (формат до видов — иначе виды придётся двигать), при
|
||||
необходимости `drawing_add_sheet` для второго листа.
|
||||
3. **`drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…)`** — бери ровно те
|
||||
проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. **Главный вид
|
||||
входит в набор сам**: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому `views=["top"]`
|
||||
даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими.
|
||||
4. **Координаты — замером, а не формулой.** `drawing_get_view_info(viewNumber)` отдаёт паспорт вида
|
||||
одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает
|
||||
начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось
|
||||
проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид
|
||||
арифметикой; отдельные точки переводит `drawing_project_point(x, y, z, viewNumber)`.
|
||||
Выводить оси из головы не надо и вредно: у КОМПАС «спереди» показывает плоскость XY детали, а
|
||||
«сверху» — X и **минус Z**, и **знаки инверсии зависят от `mainOrientation`** — формула,
|
||||
выведенная на одном чертеже, на соседнем врёт.
|
||||
5. **Разрез — до размеров, а не после.** Внутреннюю геометрию (зенковка, ступенчатое отверстие,
|
||||
паз, глубокая расточка, полость) показывай разрезом, а не невидимыми линиями: по штриховой линии
|
||||
нельзя ни поставить нормальный размер, ни разобрать форму. `drawing_add_section_view` — см.
|
||||
§«Разрез» ниже. Размеры внутренней геометрии ставятся УЖЕ НА РАЗРЕЗЕ, поэтому строить его надо
|
||||
раньше простановки, иначе размеры придётся переносить.
|
||||
6. **Размеры**, `drawing_add_axis` (осевые и центровые), шероховатость, выноски, техтребования,
|
||||
штамп. **Осевые сначала посмотри, потом добивай**: ассоциативные виды приходят со СВОИМИ
|
||||
центровыми и осевыми, которые КОМПАС ставит сам, и `drawing_add_axis` вслепую даёт дубли поверх
|
||||
существующих. Сначала `list_drawing_objects(kind="axis"|"centreMarker", viewNumber=…)`.
|
||||
7. **`drawing_export_image`** — посмотреть глазами. Пока картинки не было, чертёж не сдан.
|
||||
|
||||
### Разрез
|
||||
|
||||
`drawing_add_section_view` делает всё сразу: проводит линию разреза на базовом виде и строит по ней
|
||||
производный вид со штриховкой. Механика, ступенчатый разрез и встроенная проверка честности —
|
||||
`help(topic="drawing-sections")`; здесь только решения, которые принимаешь ты:
|
||||
|
||||
- **Разрез или `hiddenLines`.** Разрез — когда внутреннее нужно ИЗМЕРИТЬ или показать форму:
|
||||
зенковка и цековка, ступенчатое или резьбовое отверстие, паз, канавка, глубокая расточка, тонкая
|
||||
стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к
|
||||
штриховой линии не привязывают.
|
||||
- **Веди линию с запасом за габарит** (плита 60 мм → от −40 до +40): линия по самому краю режет не
|
||||
всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `drawing_get_view_info`.
|
||||
- **Строй разрез, когда модель готова**: после правки детали перестраивается только ПЕРВЫЙ разрез
|
||||
базового вида. Модель всё же изменилась — снеси разрезы и построй заново.
|
||||
- Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру.
|
||||
|
||||
**Промах простановки лечится, а не остаётся навсегда.** Отката (undo) у чертежа нет, но
|
||||
`list_drawing_objects` показывает обозначения с индексами, `drawing_delete_object` убирает одно, а
|
||||
`drawing_move_object` его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не
|
||||
заменой размера на выноску. Так же правится и компоновка: `drawing_move_view` переставляет вид со
|
||||
всеми обозначениями, `drawing_add_view` доносит недостающую проекцию, `drawing_delete_view` убирает
|
||||
лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления —
|
||||
`help(topic="drawing-fixing")`.
|
||||
|
||||
**Три вещи, на которых чертёж молча выходит неверным** — держи их в голове, детали в справочнике:
|
||||
|
||||
- `viewNumber=0` — это НЕ главный вид, а координаты ЛИСТА; знак, поставленный «на главном виде» с
|
||||
нулём, уезжает за границы формата (`help(topic="drawing-views")`);
|
||||
- ассоциативны только диаметральный и радиальный размеры; линейный и угловой меряют координаты, и
|
||||
«60» останется, когда деталь станет 70 — после правки модели перепроверяй их сам
|
||||
(`help(topic="drawing-dimensions")`);
|
||||
- допуск, не легший в размер, виден только по пустому read-back в ответе — техтребования его не
|
||||
заменят (`help(topic="drawing-dimension-text")`).
|
||||
|
||||
Ещё две ловушки, о которых узнаёшь только столкнувшись: штамп частично ведёт МОДЕЛЬ, а не чертёж
|
||||
(`help(topic="drawing-title-block")`), и у цилиндрической грани нет «координат оси» — её
|
||||
восстанавливают и проверяют сходимостью площадей (`help(topic="cylinder-axis")`).
|
||||
|
||||
**Чего нет.** Выносного элемента (увеличенный фрагмент), МЕСТНОГО разреза внутри вида, местного
|
||||
вида и вида с разрывом. Ассоциативного ЛИНЕЙНОГО размера нет и не будет: в API у него нет привязки к геометрии
|
||||
ни под каким именем (проверено QI, поздним связыванием и размером с обрывом). Экспорта в PDF/DXF
|
||||
тоже нет — наружу уходит растр (`drawing_export_image`) и STEP.
|
||||
Чертёж строится не так, как деталь: **авто-валидации здесь нет** — верность тут не про геометрию,
|
||||
а про место на листе, и проверяется только просмотром. Порядок «формат → виды → координаты замером
|
||||
→ разрез до размеров → простановка → `drawing_export_image`», разрез, три ловушки, на которых
|
||||
чертёж молча выходит неверным (`viewNumber=0`, ассоциативность размеров, допуск без read-back), и
|
||||
чего в 2D нет — [reference/drawing-playbook.md](reference/drawing-playbook.md).
|
||||
|
||||
## Работа с импортом / сборками
|
||||
|
||||
Конвейер «импорт → разбор → извлечение детали → осмотр → модификация → экспорт»:
|
||||
|
||||
1. **`import_model`** — `type` задаёт документ: `assembly` (по умолчанию) или `part`.
|
||||
Формат берётся из расширения; `.prt` и `.asm` носят несколько САПР сразу — там задавай `format`
|
||||
явно. Нужна отдельная деталь файлом — включай `createComponentFiles`: без него импорт не пишет
|
||||
на диск ничего, кроме открытого документа.
|
||||
Плоский чертёж (.dxf/.dwg) читает не он, а `import_drawing`.
|
||||
2. **Разбор:** `describe_model(sections=components)` (у каждого компонента — origin, поворот,
|
||||
фиксация) и `describe_model(sections=mates)`, если сборка пришла со связями; грани компонента —
|
||||
`list_faces(component=N)`. Извлечённую деталь открывай самостоятельным документом.
|
||||
Гашение видимости компонента на снимок **не влияет** — изоляция так не делается.
|
||||
3. **Осмотр — структурно** (`describe_model`: какая ось «высота», МЦХ, топология). Снимок
|
||||
`model_snapshot(view=…)` — ракурс выбирай по плоскости детали (плоскую смотри сверху или
|
||||
спереди, не в изометрии); один и тот же `view` даёт воспроизводимый кадр «до/после».
|
||||
**Пары ракурсов противоположны по оси:** `front` смотрит из +Z, `rear` — из −Z, так же
|
||||
`top`/`bottom` и `left`/`right`. Следствие, которое нужно чаще всего: деталь, лежащая на столе
|
||||
гранью Z=0 (эскиз на XOY, выдавливание вперёд), видна столу как **`rear`**, а `front` покажет
|
||||
зеркальную картинку. Читаемость надписи или логотипа доказывают снимком с нужной стороны, а не
|
||||
рассуждением.
|
||||
4. **Модификация «тупой» B-rep** (итог — в ответе каждой операции): простой случай — `move_face`;
|
||||
вставка N мм в призматическую ножку — `split_solid_by_plane` → `move_body` → `move_face` (мост)
|
||||
→ `boolean_union` (шаги пронумерованы в описаниях самих инструментов; цепочка проверена
|
||||
end-to-end: проставка 39.45 → 41.45 мм, построение чистое).
|
||||
5. **Перед выдачей:** последняя операция «Построение чистое» → `export_model` (STEP для обмена,
|
||||
STL для печати).
|
||||
Конвейер «импорт → разбор → извлечение детали → осмотр → модификация → экспорт» для ЧУЖОЙ модели —
|
||||
[reference/import-playbook.md](reference/import-playbook.md).
|
||||
|
||||
## Исполнения: одна модель — несколько геометрий
|
||||
|
||||
Типоразмеры (профиль на 100, 200, 500 мм), правое и левое зеркало, версии с отверстием и без часто
|
||||
живут **в одном файле** исполнениями. Тогда всё, что ты меришь и экспортируешь, относится к
|
||||
**текущему** исполнению — не к «детали вообще».
|
||||
|
||||
- **Признак замечаешь не ты, а ответ.** У модели с несколькими исполнениями `describe_model` сам
|
||||
пишет, сколько их и какое сейчас текущее. Увидел эту строку — прежде чем считать массу или резать
|
||||
чертёж, посмотри `describe_model(sections=embodiments)`: там габарит и масса **каждого**, и это
|
||||
чтение ничего не переключает.
|
||||
- **Переключение равно смене документа.** `embodiment(action="set", target="L200")` обнуляет
|
||||
сессию построения: хендлы `sk_…`/`op_…` после него мертвы. Сохраняй документ до переключения.
|
||||
- **Индекс живёт до первой правки дерева**: после `delete` индексы смещаются. Адресуй обозначением
|
||||
(«L500»), а индексом — только сразу после того, как увидел список.
|
||||
- **Строишь новое исполнение** — `embodiment(action="add", number="02")`; оно сразу становится
|
||||
текущим, строй в нём немедленно. `depended=false` нужен, когда правки НЕ должны наследоваться от
|
||||
родителя, — иначе изменение уедет и в него.
|
||||
- **В сборку исполнение выбирается явно**: `assembly_add_component(embodiment="L500")`. Без
|
||||
параметра встанет **базовое** исполнение, а не то, что сохранено в файле текущим. Обозначение
|
||||
нужно ПОЛНОЕ («ПРОБА.001-01», а не «-01»); сервер откажет, если КОМПАС подсунет базовое.
|
||||
- **«Удлинить эти профили с 500 до 600» — это смена исполнения экземпляра, а не новая вставка**:
|
||||
`embodiment(action="set", target="L600", component=N)` и затем `rebuild`. Сопряжения при этом
|
||||
**сохраняются** — пересоздание вставки, наоборот, порвало бы их все. Какие исполнения есть у
|
||||
конкретного экземпляра, показывает `describe_model(sections="embodiments", component=N)`.
|
||||
- **Выгнать всю линейку на печать** — `export_model(embodiment="all")`: каждое исполнение в свой
|
||||
файл с суффиксом обозначения.
|
||||
- **После смены исполнения в собранном узле проверь сопряжения** (`sections="mates"`): если у нового
|
||||
исполнения нет объекта, на который опиралась связь, она рвётся — «ССЫЛКА ПОТЕРЯНА», `valid: false`,
|
||||
компонент недоопределён. Что было потеряно, хранит имя сопряжения; `assembly_delete` сотрёт и его.
|
||||
|
||||
Подробности и границы — `help(topic="embodiments")`.
|
||||
Типоразмеры, зеркала, версии с отверстием и без в одном файле — переключение равно смене документа
|
||||
(хендлы гибнут), индексация и адресация в сборке, порядок «сначала геометрия, исполнения последним
|
||||
шагом» — [reference/embodiments-playbook.md](reference/embodiments-playbook.md).
|
||||
|
||||
## Эвристики и подводные камни
|
||||
|
||||
@@ -550,6 +378,32 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
- **Направление операции** (`extrude(forward)`, знак `distance` у `move_face`): на выбранной грани
|
||||
зависит от ориентации её нормали — реши ДО построения, прочитав нормаль в `list_faces(index=N)`
|
||||
(или по снимку), а после сверь сводку объёма в ответе.
|
||||
- **У ВЫРЕЗА `forward` смотрит в другую сторону, чем у прилива.** Замерено на плите Z 0..10 с
|
||||
эскизом на плоскости z=10: `extrude(mode=boss, forward=true)` наращивает ВВЕРХ, а
|
||||
`extrude(mode=cut, forward=true)` режет ВНИЗ, в тело. То есть у выреза «прямое» — это внутрь
|
||||
материала. Оба умолчания делают то, чего обычно и хотят, но рассуждение «forward — это плюс
|
||||
нормали» даст перевёрнутый карман. **Вырез, ушедший в пустоту, КОМПАС считает успехом** —
|
||||
дерево чистое, объём не изменился; ловит это только строка сверки в ответе. Поэтому у
|
||||
`extrude`/`revolve(mode=cut)` **не задавай `forward`, если сторона неочевидна**: сервер сам
|
||||
переделает вырез, не убравший материала, в обратную сторону и скажет об этом в ответе.
|
||||
Выбор работает, только если одна сторона пуста: эскиз ВНУТРИ материала (плоскость посреди вала)
|
||||
режет в обе стороны — там `forward` задавай сам и сверяй объём.
|
||||
- **На YOZ деталь растёт в МИНУС X, и туда же уезжает смещение плоскости.** Нормаль базовой
|
||||
плоскости смотрит в плюс своей оси не всегда — замерено: XOY → +Z, XOZ → +Y, а **YOZ → −X**.
|
||||
Значит `extrude(forward=true)` по эскизу на YOZ кладёт материал в отрицательные X, а
|
||||
`sketch_create(plane="YOZ", offset=30)` ставит плоскость в X = −30, а не +30. Обе вещи следуют
|
||||
одной нормали, так что путаницы между ними нет — но знак учитывай при компоновке, иначе деталь
|
||||
уедет зеркально задуманному. Таблица целиком — `help(topic="build-verification")`.
|
||||
- **`sketch_update` несущего эскиза МОЛЧА теряет часть отделки.** Фаска и скругление, снятые по
|
||||
точкам, после переиздания базового контура остаются в дереве, ошибок не дают — а построены
|
||||
оказываются не на всех рёбрах: замерено трижды на одной детали, из четырёх скруглений выживали
|
||||
то два, то одно. Иногда КОМПАС всё же сознаётся («код 145: операция потеряла опорные объекты»),
|
||||
но чаще молчит, и единственный признак — объём: он оказывается БОЛЬШЕ ожидаемого ровно на
|
||||
недоснятый материал. Порядок после каждого переиздания несущего эскиза: сверить объём с прикидкой
|
||||
либо пересчитать результат отделки (`list_faces(type="cylinder")` для скруглений — их должно быть
|
||||
ровно столько, сколько рёбер в пакете); недосчитались — снести отделочные узлы
|
||||
(`feature_delete(featureIndices=[…])`) и построить заново, уже по новым рёбрам. Пересборка
|
||||
дешевле поиска виновного, а «построение чистое» здесь не значит ничего.
|
||||
- **Эскизы и операции адресуются ХЕНДЛАМИ из ответов** — `sk_7c1e5aa3f1_1_2`, `op_7c1e5aa3f1_1_5`.
|
||||
Не сочиняй их и не передавай числа: числовая адресация не поддерживается, а сервер объяснит формат
|
||||
отказом. Хендл живёт только в текущей сессии построения: смена активного документа
|
||||
@@ -559,7 +413,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
Хендл — это НЕ индекс: `faceIndex`/`edgeIndices` из `list_faces`/`list_edges` и параметр
|
||||
`feature` у `link_parameter`/`list_parameters` (имя или индекс узла дерева) остаются числовыми.
|
||||
`primitive` и `hole` тоже возвращают хендл (у `hole` — по одному на КАЖДОЕ отверстие серии),
|
||||
так что примитив и отверстие можно удалить `feature_delete` и размножить `pattern`/`mirror`.
|
||||
так что примитив и отверстие можно удалить `feature_delete` и размножить `pattern` (и `kind=mirror`).
|
||||
Если ответ вместо хендла говорит «выдать не удалось» — операция построена, но адресовать её
|
||||
нечем: переставить её потом можно только пересборкой.
|
||||
- **Единицы — мм** (геометрия) и **кг** (масса). Локальные координаты эскиза ≠ мировые координаты
|
||||
@@ -580,7 +434,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
сохранения.
|
||||
|
||||
- **Строишь параллельно с кем-то — `instance="private"`** при первом `kompas_connect` (потом режим
|
||||
не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_set_visible true`
|
||||
не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_connect(visible=true)`
|
||||
покажет).
|
||||
- **`shared` оставляй**, когда работа идёт на глазах у человека и ты единственный агент.
|
||||
- **Один файл в двух экземплярах не открыть** — второй получит его только на чтение: работу делите
|
||||
@@ -588,9 +442,12 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
||||
|
||||
## Открытые вопросы / границы
|
||||
|
||||
- **Параметрика работает через параметры ОПЕРАЦИЙ, а не размеры эскиза** — сдвинуть контур
|
||||
переменной нельзя, только пересобрать эскиз. Планируй членение так, чтобы изменяемое задавалось
|
||||
параметром операции (глубина, радиус, габарит примитива), а не координатами в эскизе.
|
||||
- **Координата в точке — число или выражение (считается один раз), а форму контура ведут `dimensions`** с выражениями
|
||||
(`help(topic="sketch-dimensions")`). Уже наложенный размер перепривязывается без пересборки:
|
||||
`link_parameter(feature=<узел эскиза>, parameter="v15")` — имя `vNN` есть в ответе
|
||||
`sketch_create` и в `list_parameters` (у одноимённых «Линейный размер» — в скобках). Эскиз без
|
||||
размеров переменной не двигается — только пересборкой (`sketch_update`); положение эскиза задаёт
|
||||
**плоскость** — обычный узел с параметром «Расстояние».
|
||||
- **2D покрыт вместе с разрезом и сечением.** Есть виды (с выбором набора, ориентации главного и
|
||||
невидимых линий), разрез/сечение, листы, штамп, размеры с допусками, осевые, обозначения,
|
||||
техтребования, удаление и сдвиг объекта, вывод в растр — методика в §«Чертёж». Нет выносного
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# Сборка: собрать своё
|
||||
|
||||
Дополнение к SKILL.md — методика для сборки С НУЛЯ. Разбор ЧУЖОЙ сборки (пришедшей STEP/импортом) —
|
||||
`reference/import-playbook.md`.
|
||||
|
||||
Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.**
|
||||
|
||||
1. **Детали сначала сохрани в файлы.** Компонент вставляется ссылкой на `.m3d`/`.a3d`, поэтому
|
||||
несохранённую деталь вставить нельзя.
|
||||
2. **`document_create assembly` → `assembly_add_component(filePath, x, y, z, rx, ry, rz)`.** Углы — в
|
||||
градусах, вокруг СОБСТВЕННЫХ осей компонента и по очереди X→Y→Z: второй угол считается уже от
|
||||
повёрнутого положения. Пока задан один угол, разницы с мировыми осями нет.
|
||||
3. **Зафиксируй базовую деталь СРАЗУ: `assembly_fix_component(componentIndex=0, fixedState=true)`.** КОМПАС не закрепляет
|
||||
никого сам, включая первый компонент, и решатель двигает того, кого сочтёт нужным — в том числе
|
||||
основание, вокруг которого ты собираешь всё остальное. Это самая частая причина «сопряжение
|
||||
верное, а сборка расползлась».
|
||||
4. **Сопрягай:** `assembly_add_mate(mateType, …)` — семь типов, адресация гранью и смысл
|
||||
`orientation` в `help(topic="assembly-mates")`. Что решаешь ты, а не справочник:
|
||||
- **Грань адресуй индексом, а не координатами:** `list_faces(component=N)` → пара
|
||||
`faceIndex`+`componentIndex`. Точки на бумаге считать не нужно, и сервер сам проверит, что
|
||||
грань принадлежит этому компоненту.
|
||||
- **Сторону зазора у `distance` задаёт ВЫБОР ПАРЫ ГРАНЕЙ, и от стартового положения она не
|
||||
зависит.** «Closest» — не «ближайшее»: при сонаправленных нормалях объект 1 садится со стороны
|
||||
−n относительно объекта 2 (замерено двойным прогоном). Практическое правило: бери пару граней,
|
||||
которые смотрят ДРУГ НА ДРУГА. Вышло зеркально — меняй грань, а не `orientation`.
|
||||
- **Первое сопряжение вешай на зафиксированную деталь.** Пока в цепочке нет ни одного
|
||||
закреплённого звена, решатель волен двигать любое; связка «каждый новый компонент — к уже
|
||||
стоящему на месте» разваливается вдвое реже, чем связка «все ко всем».
|
||||
5. **`rebuild`,** если авто-валидация написала «ℹ Требуется перестроение». Это НЕ ошибка построения:
|
||||
так помечает себя свежий компонент или только что наложенная связь. Бросать работу здесь не надо
|
||||
— правило «не продолжай при ⚠» касается строки со знаком ⚠, а не этой.
|
||||
**Исключение из правила «⚠ = стоп».** После КАЖДОГО сопряжения авто-валидация пишет
|
||||
«⚠ N операц. в ошибке: „Сопряжения“ (код 0: ошибки нет)». Это то же «требуется перестроение»,
|
||||
только под знаком ⚠: код 0 и имя операции «Сопряжения» означают, что ломаться нечему. Делай
|
||||
`rebuild` и иди дальше. Настоящая беда со связью видна не здесь, а в
|
||||
`describe_model(sections=mates)` — по пометке `valid:false`.
|
||||
6. **Проверь:**
|
||||
- `describe_model(sections=components)` — origin, поворот ЧИСЛАМИ (`rx/ry/rz` в градусах, та же
|
||||
семантика, что у вставки) и «зафиксирован/свободен» у каждого: этим и видно, КОГО и НА СКОЛЬКО
|
||||
подвинул решатель;
|
||||
- `describe_model(sections=mates)` — что с чем связано, с каким значением и не выродилось ли.
|
||||
Это ключевой детектор: `assembly_add_mate` может ответить успехом, а связь окажется
|
||||
вырожденной;
|
||||
- `measure(kind1=face, index1=…, componentIndex1=…, kind2=face, index2=…, componentIndex2=…)` —
|
||||
зазор между деталями напрямую, без арифметики по габаритам;
|
||||
- `assembly_check_interference(componentIndex1, componentIndex2)` — **не налезли ли детали друг
|
||||
на друга.** Проверяй все пары, которые должны идти впритирку.
|
||||
|
||||
**Неудачную связь не нужно пересобирать с нуля:** `assembly_delete(target="mate"|"component", index)`
|
||||
снимает сопряжение или компонент вместе с опирающимися на него связями. Индексы после удаления
|
||||
сдвигаются — иди от больших к меньшим и перечитывай `describe_model(sections=mates)`.
|
||||
|
||||
**Пересечение деталей не видно НИГДЕ, кроме `assembly_check_interference`.** Сборка складывается из
|
||||
готовых тел, и КОМПАС их не вычитает: две детали могут занимать общий объём, а сопряжения при этом
|
||||
останутся `valid`, раздел `errors` — пустым, объём экспорта — простой суммой компонентов. `measure`
|
||||
тоже не спасает: нулевой зазор одинаково означает и касание, и взаимопроникновение. Проверяй все
|
||||
пары, которые должны идти впритирку.
|
||||
|
||||
**«Тела: 0» в сборке означает не «пусто», а «спрошено не то»:** тела принадлежат компонентам
|
||||
(`describe_model(component=N, …)`), а `box` и `mass` без `component` честно дают габарит и МЦХ сборки
|
||||
целиком. Про разные системы координат внутри паспорта компонента —
|
||||
`help(topic="model-inspection")`; про локальные координаты граней и `pointOnFace` —
|
||||
`help(topic="face-addressing")`.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Чертёж: оформить деталь по ГОСТ
|
||||
|
||||
Дополнение к SKILL.md — методика оформления 2D-чертежа. Чертёж строится не так, как деталь:
|
||||
**авто-валидации здесь нет**. Правило трёх проверок из SKILL.md §«Два правила прежде всего» в 2D не
|
||||
работает — операция не отчитывается «построилось верно», потому что верность тут не про геометрию,
|
||||
а про место на листе. Проверять приходится самому, и способ ровно один: посмотреть.
|
||||
|
||||
**Порядок, который окупается:**
|
||||
|
||||
1. **Деталь строится в чертёжной ориентации.** Набор видов задаётся ОТ модели: `mainOrientation`
|
||||
выбирает, какую ориентацию модели показывает главный вид, но саму ориентацию модели он не
|
||||
вращает. Если самая информативная проекция детали — не одна из шести стандартных, чертежа по
|
||||
ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость
|
||||
с наибольшей информацией.
|
||||
2. **`drawing_set_sheet_format`** (формат до видов — иначе виды придётся двигать), при
|
||||
необходимости `drawing_set_sheet_format(add=true)` для второго листа.
|
||||
3. **`drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…)`** — бери ровно те
|
||||
проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. **Главный вид
|
||||
входит в набор сам**: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому `views=["top"]`
|
||||
даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими.
|
||||
4. **Координаты — замером, а не формулой.** `describe_drawing(sections=view, viewNumber)` отдаёт паспорт вида
|
||||
одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает
|
||||
начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось
|
||||
проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид
|
||||
арифметикой; отдельные точки переводит `drawing_project_point(x, y, z, viewNumber)`.
|
||||
Выводить оси из головы не надо и вредно: у КОМПАС «спереди» показывает плоскость XY детали, а
|
||||
«сверху» — X и **минус Z**, и **знаки инверсии зависят от `mainOrientation`** — формула,
|
||||
выведенная на одном чертеже, на соседнем врёт.
|
||||
5. **Разрез — до размеров, а не после.** Внутреннюю геометрию (зенковка, ступенчатое отверстие,
|
||||
паз, глубокая расточка, полость) показывай разрезом, а не невидимыми линиями: по штриховой линии
|
||||
нельзя ни поставить нормальный размер, ни разобрать форму. `drawing_add_section_view` — см.
|
||||
§«Разрез» ниже. Размеры внутренней геометрии ставятся УЖЕ НА РАЗРЕЗЕ, поэтому строить его надо
|
||||
раньше простановки, иначе размеры придётся переносить.
|
||||
6. **Размеры**, `drawing_add_axis` (осевые и центровые), шероховатость, выноски, техтребования,
|
||||
штамп. **Осевые сначала посмотри, потом добивай**: ассоциативные виды приходят со СВОИМИ
|
||||
центровыми и осевыми, которые КОМПАС ставит сам, и `drawing_add_axis` вслепую даёт дубли поверх
|
||||
существующих. Сначала `describe_drawing(kind="axis"|"centreMarker", viewNumber=…)`.
|
||||
7. **`drawing_export_image`** — посмотреть глазами. Пока картинки не было, чертёж не сдан.
|
||||
|
||||
## Разрез
|
||||
|
||||
`drawing_add_section_view` делает всё сразу: проводит линию разреза на базовом виде и строит по ней
|
||||
производный вид со штриховкой. Механика, ступенчатый разрез и встроенная проверка честности —
|
||||
`help(topic="drawing-sections")`; здесь только решения, которые принимаешь ты:
|
||||
|
||||
- **Разрез или `hiddenLines`.** Разрез — когда внутреннее нужно ИЗМЕРИТЬ или показать форму:
|
||||
зенковка и цековка, ступенчатое или резьбовое отверстие, паз, канавка, глубокая расточка, тонкая
|
||||
стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к
|
||||
штриховой линии не привязывают.
|
||||
- **Веди линию с запасом за габарит** (плита 60 мм → от −40 до +40): линия по самому краю режет не
|
||||
всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `describe_drawing(sections=view)`.
|
||||
- **Строй разрез, когда модель готова**: после правки детали перестраивается только ПЕРВЫЙ разрез
|
||||
базового вида. Модель всё же изменилась — снеси разрезы и построй заново.
|
||||
- Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру.
|
||||
|
||||
**Промах простановки лечится, а не остаётся навсегда.** Отката (undo) у чертежа нет, но
|
||||
`describe_drawing` показывает обозначения с индексами, `drawing_delete(target=object)` убирает одно, а
|
||||
`drawing_move_object` его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не
|
||||
заменой размера на выноску. Так же правится и компоновка: `drawing_move_view` переставляет вид со
|
||||
всеми обозначениями, `drawing_create_standard_views(views=[])` доносит недостающую проекцию, `drawing_delete(target=view)` убирает
|
||||
лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления —
|
||||
`help(topic="drawing-fixing")`.
|
||||
|
||||
**Три вещи, на которых чертёж молча выходит неверным** — держи их в голове, детали в справочнике:
|
||||
|
||||
- `viewNumber=0` — это НЕ главный вид, а координаты ЛИСТА; знак, поставленный «на главном виде» с
|
||||
нулём, уезжает за границы формата (`help(topic="drawing-views")`);
|
||||
- ассоциативны только диаметральный и радиальный размеры; линейный и угловой меряют координаты, и
|
||||
«60» останется, когда деталь станет 70 — после правки модели перепроверяй их сам
|
||||
(`help(topic="drawing-dimensions")`);
|
||||
- допуск, не легший в размер, виден только по пустому read-back в ответе — техтребования его не
|
||||
заменят (`help(topic="drawing-dimension-text")`).
|
||||
|
||||
Ещё две ловушки, о которых узнаёшь только столкнувшись: штамп частично ведёт МОДЕЛЬ, а не чертёж
|
||||
(`help(topic="drawing-title-block")`), и у цилиндрической грани нет «координат оси» — её
|
||||
восстанавливают и проверяют сходимостью площадей (`help(topic="cylinder-axis")`).
|
||||
|
||||
**Чего нет.** Выносного элемента (увеличенный фрагмент), МЕСТНОГО разреза внутри вида, местного
|
||||
вида и вида с разрывом. Ассоциативного ЛИНЕЙНОГО размера нет и не будет: в API у него нет привязки к геометрии
|
||||
ни под каким именем (проверено QI, поздним связыванием и размером с обрывом). Экспорта в PDF/DXF
|
||||
тоже нет — наружу уходит растр (`drawing_export_image`) и STEP.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Исполнения: одна модель — несколько геометрий
|
||||
|
||||
Дополнение к SKILL.md. Типоразмеры (профиль на 100, 200, 500 мм), правое и левое зеркало, версии с
|
||||
отверстием и без часто живут **в одном файле** исполнениями. Тогда всё, что ты меришь и
|
||||
экспортируешь, относится к **текущему** исполнению — не к «детали вообще».
|
||||
|
||||
- **Признак замечаешь не ты, а ответ.** У модели с несколькими исполнениями `describe_model` сам
|
||||
пишет, сколько их и какое сейчас текущее. Увидел эту строку — прежде чем считать массу или резать
|
||||
чертёж, посмотри `describe_model(sections=embodiments)`: там габарит и масса **каждого**, и это
|
||||
чтение ничего не переключает.
|
||||
- **Переключение равно смене документа.** `embodiment(action="set", target="L200")` обнуляет
|
||||
сессию построения: хендлы `sk_…`/`op_…` после него мертвы. Сохраняй документ до переключения.
|
||||
- **Индекс живёт до первой правки дерева**: после `delete` индексы смещаются. Адресуй обозначением
|
||||
(«L500»), а индексом — только сразу после того, как увидел список. У **варианта** обозначение
|
||||
родительское, и адресовать его номером нельзя вовсе — под «-01» подходят двое; зови его по имени
|
||||
(«M5-01») или индексом.
|
||||
- **Исполнения делай ПОСЛЕДНИМ шагом.** Переключение убивает хендлы, и дальнейшая правка дерева
|
||||
идёт уже через `feature_delete(featureIndex=…)` по `describe_model(sections=tree)` — путь рабочий,
|
||||
но менее удобный. Сначала доведи базовую геометрию и параметризацию, потом размножай.
|
||||
- **Строишь новое исполнение** — `embodiment(action="add", number="02")`; оно сразу становится
|
||||
текущим, строй в нём немедленно. `depended=false` нужен, когда правки НЕ должны наследоваться от
|
||||
родителя, — иначе изменение уедет и в него.
|
||||
- **В сборку исполнение выбирается явно**: `assembly_add_component(embodiment="L500")`. Без
|
||||
параметра встанет **базовое** исполнение, а не то, что сохранено в файле текущим. Обозначение
|
||||
нужно ПОЛНОЕ («ПРОБА.001-01», а не «-01»); сервер откажет, если КОМПАС подсунет базовое.
|
||||
- **«Удлинить эти профили с 500 до 600» — это смена исполнения экземпляра, а не новая вставка**:
|
||||
`embodiment(action="set", target="L600", component=N)` и затем `rebuild`. Сопряжения при этом
|
||||
**сохраняются** — пересоздание вставки, наоборот, порвало бы их все. Какие исполнения есть у
|
||||
конкретного экземпляра, показывает `describe_model(sections="embodiments", component=N)`.
|
||||
- **Исполнения, отличающиеся одним размером, — это переменная, а не правка дерева.** Значение
|
||||
переменной каждое исполнение (и вариант) хранит СВОЁ: `set_variable` после `embodiment(add)`
|
||||
меняет только текущее, у наследников выражение становится ссылкой на родителя
|
||||
(`VCM.001|fit_h`). Отсюда приём: построй базу на переменных, затем `add` → `set_variable` в
|
||||
каждом исполнении. Убрать элемент в исполнении часто проще значением, чем `feature_delete`:
|
||||
цековка с `cb_d = hole_d` уходит в уже вырезанное.
|
||||
- **Выгнать всю линейку на печать** — `export_model(embodiment="all")`: каждое исполнение в свой
|
||||
файл с суффиксом обозначения.
|
||||
- **После смены исполнения в собранном узле проверь сопряжения** (`sections="mates"`): если у нового
|
||||
исполнения нет объекта, на который опиралась связь, она рвётся — «ССЫЛКА ПОТЕРЯНА», `valid: false`,
|
||||
компонент недоопределён. Что было потеряно, хранит имя сопряжения; `assembly_delete` сотрёт и его.
|
||||
|
||||
Подробности и границы — `help(topic="embodiments")`.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Фрагмент — переиспользуемый чертёж, а не сечение
|
||||
|
||||
Дополнение к SKILL.md. Эскиз живёт внутри дерева построения и вне его не существует; фрагмент (*.frw)
|
||||
— самостоятельный файл, который переживает деталь. `fragment_create` его пишет, `fragment_place`
|
||||
кладёт в активный чертёж или другой фрагмент, а `mode` решает, чем он там станет — и это разные
|
||||
объекты, а не оттенки одного:
|
||||
|
||||
- **`reference`** — вставка-ссылка: содержимым владеет файл, правка файла меняет все документы, куда
|
||||
он вставлен. Ради этого фрагменты и заводят: одна заготовка на десять чертежей.
|
||||
- **`copy`** — копия внутри документа, живёт своей жизнью; файл потом можно удалить.
|
||||
- **`local`** — вставка, переиспользуемая только внутри этого документа.
|
||||
- **`explode`** — россыпь обычных примитивов: правится по одному, но связи с файлом уже нет.
|
||||
|
||||
**Имя вставки общее у вставок одного файла одного вида.** Вторая копия того же файла получает имя
|
||||
первой, и `name` второго вызова не применяется. Ответ `fragment_place` называет фактическое имя
|
||||
и прямо говорит, если запрошенное не легло. Нужны разные имена — кладите разные файлы.
|
||||
|
||||
`angle` (градусы), `scale` и `mirror` задают размещение; зеркалить можно только вставку — у россыпи
|
||||
отражать нечего. **Зеркало отражает относительно вертикали через точку вставки**, поэтому контур
|
||||
уходит в другую сторону от неё: вставка в x=220 после `mirror` занимает 160…220, а не 220…280.
|
||||
|
||||
Проверять результат — `describe_drawing`: он показывает состав по типам, габарит и все вставки
|
||||
с их файлами. Вставка, чей файл потерялся, рисуется пустым местом — в списке она помечена
|
||||
недействительной, и это единственный способ отличить её от удавшейся, не глядя на экран.
|
||||
|
||||
Контур, который переживёт конкретную деталь (логотип, шаблон, профиль), клади во фрагмент —
|
||||
`fragment_create(path, entities)` тем же списком примитивов. Активный документ он не подменяет,
|
||||
поэтому фрагмент можно снять посреди построения детали; габарит в ответе снят с самого документа —
|
||||
сверяй его с задуманным.
|
||||
@@ -0,0 +1,60 @@
|
||||
# Работа с импортом / сборками
|
||||
|
||||
Дополнение к SKILL.md — конвейер разбора ЧУЖОЙ модели/сборки: «импорт → разбор → извлечение детали →
|
||||
осмотр → модификация → экспорт». Сборка С НУЛЯ — `reference/assembly-playbook.md`.
|
||||
|
||||
1. **`import_model`** — `type` задаёт документ: `assembly` (по умолчанию) или `part`.
|
||||
Формат берётся из расширения; `.prt` и `.asm` носят несколько САПР сразу — там задавай `format`
|
||||
явно. Нужна отдельная деталь файлом — включай `createComponentFiles` (по умолчанию `false`).
|
||||
**Выключенный переключатель чистого диска НЕ гарантирует:** конвертер пишет файлы рядом с
|
||||
ИСХОДНИКОМ и помимо него — замерено, четыре импорта положили четыре незапрошенных `.m3d`.
|
||||
Что реально изменилось в каталоге исходника, ответ перечисляет поимённо; не хочешь засорять
|
||||
чужой каталог — копируй файл во временный (`help(topic="model-exchange")`).
|
||||
**STL/OBJ приходят СЕТКОЙ:** «тел 0, объём 0.0 мм³» после такого импорта — норма, а не провал,
|
||||
проверяй габаритом; ответ говорит это вслух и называет число треугольников из самого файла.
|
||||
Плоский чертёж (.dxf/.dwg) читает не он, а `import_drawing`.
|
||||
2. **Разбор:** `describe_model(sections=components)` (у каждого компонента — origin, поворот,
|
||||
фиксация) и `describe_model(sections=mates)`, если сборка пришла со связями; грани компонента —
|
||||
`list_faces(component=N)`. Извлечённую деталь открывай самостоятельным документом.
|
||||
Гашение видимости компонента на снимок **не влияет** — изоляция так не делается.
|
||||
3. **Осмотр — структурно** (`describe_model`: какая ось «высота», МЦХ, топология). Снимок
|
||||
`model_snapshot(view=…)` — ракурс выбирай по плоскости детали (плоскую смотри сверху или
|
||||
спереди, не в изометрии); один и тот же `view` даёт воспроизводимый кадр «до/после».
|
||||
**Пары ракурсов противоположны по оси:** `front` смотрит из +Z, `rear` — из −Z, так же
|
||||
`top`/`bottom` и `left`/`right`. Следствие, которое нужно чаще всего: деталь, лежащая на столе
|
||||
гранью Z=0 (эскиз на XOY, выдавливание вперёд), видна столу как **`rear`**, а `front` покажет
|
||||
зеркальную картинку. Читаемость надписи или логотипа доказывают снимком с нужной стороны, а не
|
||||
рассуждением.
|
||||
**Но «ортогонально» — правило про ПЛОСКУЮ деталь.** Как только форма выходит из одной плоскости
|
||||
(кронштейн, косынка, изогнутый профиль), ортогональный кадр перестаёт читаться: он плоский,
|
||||
подписей осей на нём нет, и сопоставить увиденное с координатами не выходит — `right` даёт
|
||||
картинку, по которой не сказать, где перёд. Профиль такой детали смотри `view="iso"`: там видно,
|
||||
что куда загнуто.
|
||||
4. **Модификация «тупой» B-rep** (итог — в ответе каждой операции). Инструмент выбирается по тому,
|
||||
ЧТО задано в требовании, а не по тому, что привычнее:
|
||||
|
||||
| Требование звучит как | Инструмент | Почему не `move_face` |
|
||||
|---|---|---|
|
||||
| «сдвинуть грань на N мм» | `move_face` | это он и есть |
|
||||
| «диаметр отверстия (бобышки) должен стать D» | **`resize_face`** | задаётся ДИАМЕТР, ось не двигается; `move_face` сдвинул бы стенку на (D−d)/2, и это пришлось бы считать самому |
|
||||
| «грань должна встать НА объект: на плоскость, на грань соседнего тела» | **`replace_face`** | расстояние считает КОМПАС; `move_face` требует вычислить его заранее |
|
||||
| «убрать отверстие / скругление / фаску» с импорта (дефичеринг) | **`remove_face`** | соседние грани затягивают место сами; заливка отверстия телом и вычитание — лишние операции. `saveBody=false` оставляет дыру (тело-оболочка, объём 0) — нужен только если надо именно её |
|
||||
| «увеличить / уменьшить деталь целиком», компенсация усадки (1.004) | **`scale_body`** | `scale` равномерно или `scaleX/Y/Z`; центр — начало координат либо `x,y,z`; объём сверяется ×kx·ky·kz. Размеры эскизов и переменные остаются прежними — масштабируется тело |
|
||||
| вставка N мм в призматическую ножку | `split_solid_by_plane` → `move_body` → `move_face` (мост) → `boolean` | цепочка проверена end-to-end: проставка 39.45 → 41.45 мм |
|
||||
|
||||
`resize_face`, `replace_face` и `remove_face` требуют КОМПАС v25; на версиях старше они отвечают отказом с
|
||||
номером установленной версии, и тогда остаётся `move_face` с арифметикой.
|
||||
|
||||
**Проверяйте прямое редактирование РАЗНОСТЬЮ ОБЪЁМОВ против аналитической формулы** — объём и так
|
||||
печатается в сводке каждой операции, лишних вызовов не нужно. Расточка отверстия обязана снять
|
||||
ровно `π(R²−r²)·h`, наращивание грани — добавить ровно `площадь_грани × Δh`. Считайте формулу по
|
||||
СВОИМ числам и сверяйте с тем, что напечатала операция: одно число ловит и «операция ушла не
|
||||
туда», и «отверстие перестало быть сквозным».
|
||||
|
||||
**Оси отверстий сверяют полем `axis`.** У грани типа `cylinder`, `cone`, `torus` `list_faces`
|
||||
отдаёт `axis` — точку на оси и направление, в мировых координатах; у цилиндра и сферы там же
|
||||
`radius`. Требование «оси сдвигать нельзя» доказывается сравнением `axis` до и после, а не
|
||||
арифметикой по расстояниям. Осторожно с двумя соседними полями: `normal` у цилиндра — про
|
||||
сторону поверхности, а не про ось, а `pointOnFace` лежит на стенке (help(topic="cylinder-axis")).
|
||||
5. **Перед выдачей:** последняя операция «Построение чистое» → `export_model` (STEP для обмена,
|
||||
STL для печати).
|
||||
@@ -0,0 +1,67 @@
|
||||
# Параметризация: сначала переменные, потом геометрия
|
||||
|
||||
Дополнение к SKILL.md §«Параметризация». Читай это перед первым эскизом нового документа — план
|
||||
переменными стоит один вызов на размер, пока деталь пуста, и пересборку после десятка операций.
|
||||
|
||||
**В новом документе первым делом опиши будущую модель переменными — до первого эскиза.** Набор
|
||||
переменных — это план построения числами и паспорт, по которому человек поймёт модель, не разбирая
|
||||
дерево.
|
||||
|
||||
- **Заводи переменной то, что было РЕШЕНИЕМ**: габариты из ТЗ, толщины, зазоры, отступы, кегли,
|
||||
радиусы. Выводимое задавай формулой (`plate_L = badge_L - 2*edge_gap`) — правка ведущего размера
|
||||
пересчитает зависимые сама. Позиции, подобранные замером, оставляй числами: связь — обещание,
|
||||
что правка переменной даст осмысленный результат, а на позиционных числах она чаще ломает деталь.
|
||||
- **Размер передавай выражением прямо в операцию** (`extrude(depth="badge_T")`) — параметр сразу
|
||||
становится ведомым, внутреннее имя параметра («Расстояние 1») знать не нужно. Переменная должна
|
||||
существовать ДО операции — потому паспорт и заводят первым. Задним числом и для параметров,
|
||||
которых нет среди аргументов инструмента (углы уклона, второе направление), — `link_parameter`.
|
||||
- **Размер КОНТУРА — тоже выражением**, но не в координатах, а в `dimensions` у
|
||||
`sketch_create`/`sketch_update`: ширина, длина отрезка, Ø/R, а с `to` — расстояние между точками
|
||||
(шаг отверстий, отступ от края) и угол между отрезками. Координаты достаточно нарисовать
|
||||
примерно — контур встанет по значению сразу.
|
||||
- **Эскиз определён полностью, только когда привязан к модели.** Форма — размерами, положение —
|
||||
от начала координат и осей: `to:{ref:"origin"}` (расстояние от базовых плоскостей, угол или
|
||||
центр в начало через `coincident`), `coincident` с `ref:"xAxis"|"yAxis"` (точка на оси),
|
||||
`symmetric` с `axis` (деталь симметрична оси — ширина растёт в обе стороны). Порядок для
|
||||
каждого эскиза: **(1) где он стоит** — привязка к началу координат/осям; **(2) форма** — все
|
||||
длины, радиусы, углы; **(3) взаимное положение** элементов — от привязанного контура или от
|
||||
оси. Симметричную деталь строй симметрично оси модели: тогда её плоскости симметрии совпадают с
|
||||
базовыми, и следующие эскизы привязываются к тем же осям. Нужна симметрия на уровне грани —
|
||||
ставь эскиз не на грань, а на базовую плоскость со смещением (`offset`): у грани осей модели нет.
|
||||
- **Читай хвост ответа.** «полностью определён» без строки «Закреплено там, где нарисовано» —
|
||||
цель. Строка «Закреплено…» значит, что положение держит закреплённая сервером точка, а не
|
||||
привязка: добавь `ref`. «⚠ НЕДООПРЕДЕЛЁН» — часть контура свободна и сдвинется при смене
|
||||
переменной: допиши размер (чаще всего радиус дуги, угол наклонного отрезка или вторую ось
|
||||
положения). Отказ «размер ЛИШНИЙ» — величина уже следует из других (касание, сшивка, симметрия)
|
||||
— убери один. Поля, правила опоры и пример VESA — `help(topic="sketch-dimensions")`.
|
||||
- **Промахи сервер ловит сам:** ссылка на несуществующее имя — отказ с перечнем виновных (и в
|
||||
выражениях операций, и в `set_variable`), функции в формулах — предупреждение
|
||||
(тригонометрия в радианах, разделитель аргументов «;», непонятая запись = молчаливый 0).
|
||||
Имена: в ФОРМУЛЕ регистр значим (`aq` не найдёт `Aq`), а две переменные, различающиеся только
|
||||
регистром, не уживаются — `spl_d` перезапишет `spl_D`. Константы π нет: заведи `dg =
|
||||
0.017453292519943295` (градус в радианах) и пиши `sin(a*dg)`.
|
||||
- **Связь — ограничением, а не арифметикой.** Центр дуги на окружности — `coincident` с
|
||||
`to.point: "curve"`; опора вне профиля (основная окружность, ось паза) — примитив с
|
||||
`construction: true`; сторона «в 3.5 от оси под 22.5°» — `distance` до `origin` плюс `angle` к
|
||||
оси. Так связь живёт в эскизе и переживает смену переменной; посчитанные числа — нет.
|
||||
- **Считает КОМПАС, а не ты:** связь — ограничением в эскизе, скругление — примитивом `fillet`,
|
||||
точная начальная координата — выражением прямо в точке (`{"x": "rb*sin(phi*dg)"}`). Заводить
|
||||
переменные-калькуляторы и переносить их значения в JSON не нужно. Твоя часть — **сверить
|
||||
результат с прикидкой** (`sketch_describe`).
|
||||
- **`note` обязателен** и пишется по-русски, со смыслом и единицей; `(ТЗ)` в тексте по-прежнему
|
||||
полезен человеку, но для машины число из ТЗ метится ПРИЗНАКОМ:
|
||||
`set_variable([{name:"dish_r", expression:"90", note:"по ТЗ", information:true}])`. Комментарий
|
||||
вычистка не читает, признак — читает. **Что замерил — верни в переменную** (фактический кегль,
|
||||
прирост каймы), иначе паспорт разойдётся с моделью и станет дезинформацией. Переосмысливать можно
|
||||
всё, кроме помеченного `(ТЗ)`.
|
||||
- **После связывания правка паспорта перестраивает деталь** (проверено: `set_variable(badge_T=4)` →
|
||||
габарит по Z 3.00 → 4.00, объём 5154.5 → 5861.5 мм³). Это и есть параметрическая модель,
|
||||
а не комментарий к ней. **До связывания — не перестраивает**, и `set_variable` говорит об этом
|
||||
прямо: «⚠ НИЧЕГО НЕ ВЕДЁТ». Такой ответ — не успех: число поменялось, деталь нет. Исключение одно —
|
||||
переменная и не должна ничего вести (справка из ТЗ): пометь её `information=true`, и пометка уйдёт
|
||||
вместе с риском вычистки.
|
||||
- **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт» — это либо забытая
|
||||
связь, либо справка, которую забыли пометить, либо мусор; разбери все три.
|
||||
`delete_variable(unused=true)` не трогает справочные (`information`) и внешние (`external`) —
|
||||
остальное сносит без разбора. Значит порядок такой: `link_parameter` на всё, что должно вести
|
||||
геометрию, `set_variable(information=true)` на всё, что остаётся справкой, и только потом уборка.
|
||||
@@ -1,10 +1,65 @@
|
||||
# Надписи и рельеф — точная подгонка и отделка
|
||||
|
||||
Дополнение к разделу «Надписи, логотипы и рельеф» SKILL.md. Здесь — замеры и приёмы для точной
|
||||
компоновки надписи (подгонка кегля и ширины, поведение каймы, стыковка блоков) и отделки рельефа.
|
||||
Все числа получены пробами на конкретных начертаниях (Lobster, Bevan, Zilla Slab): это порядок
|
||||
величины и форма зависимости, а не константы — свои значения перезамеряй на своём шрифте,
|
||||
`widthFactor` и `thinThickness`.
|
||||
Дополнение к разделу «Надписи, логотипы и рельеф» SKILL.md: выбор маршрута для внешнего контура,
|
||||
перевод SVG-логотипа в примитивы эскиза, точная подгонка надписи (кегль, ширина, кайма, стыковка
|
||||
блоков) и отделка рельефа. Все числа получены пробами на конкретных начертаниях (Lobster, Bevan,
|
||||
Zilla Slab): это порядок величины и форма зависимости, а не константы — свои значения перезамеряй
|
||||
на своём шрифте, `widthFactor` и `thinThickness`.
|
||||
|
||||
## Внешний контур: не диктуй координаты, если фигуру нельзя описать формулой
|
||||
|
||||
Три маршрута, и выбор между ними механический — не по вкусу, а по происхождению геометрии.
|
||||
|
||||
| Откуда фигура | Чем строить |
|
||||
|---|---|
|
||||
| **Вычисляется**: пластины, рёбра, сетка отверстий | `sketch_create(entities[])` — прямо в вызове, размеры вяжи переменными |
|
||||
| **Срисована**: логотип, шаблон, кулачок, профиль | внешний вектор → JSON → `sketch_create(entitiesFile=…)` |
|
||||
| **Пришла в CAD-формате**: файл от смежника | `import_drawing` (.dxf/.dwg) → фрагмент → `fragment_place` |
|
||||
|
||||
**Обводка занимает сотни примитивов, и переписывать их в тело вызова незачем.** У `sketch_create`,
|
||||
`sketch_update(mode=append)` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`;
|
||||
сервер читает файл сам. Замер на эмблеме Volvo: SVG в 1.5 КБ даёт 96 примитивов (50 отрезков +
|
||||
46 дуг) и 9.5 КБ JSON; через `entitiesFile` это один вызов на одну строку аргументов, а эскиз
|
||||
строится за один заход. Оба параметра можно задать вместе — сначала `entities`, следом файл:
|
||||
так к готовому контуру дописывают рамку или ось, не трогая файл.
|
||||
|
||||
Что проверить **до** постройки, а не после: габарит в ответе (`fragment_create` печатает
|
||||
фактический — сверь с задуманным) и вложенные контуры. Правил заливки у эскиза КОМПАС нет: любой
|
||||
вложенный контур он режет как отверстие, даже там, где вектор заливал материал. Конвертер такие
|
||||
места называет заранее — на них смотри до выдавливания, иначе дыры обнаружатся на снимке.
|
||||
|
||||
## Логотип, которого нет в шрифте: SVG → примитивы эскиза
|
||||
|
||||
Переводи готовый вектор в примитивы эскиза сам — `line` и `arc3points`, а не ломаной: контур из
|
||||
сотен звеньев даёт деталь в сотни граней, и фаска по такому низу не строится. Кубические Безье режь
|
||||
пополам, пока дуга по трём точкам не ляжет в допуск. Четыре вещи, каждая из которых стоила захода:
|
||||
|
||||
- **Ось Y в SVG смотрит вниз** — без инверсии контур встаёт вверх ногами, и это видно только на снимке.
|
||||
- **Дуги задавай тремя точками** (`arc3points`): концы заданы явно, соседние примитивы стыкуются
|
||||
точно. Перед постройкой проверь цепочку — конец примитива против начала следующего, разрыв 0.
|
||||
- **Чисти мелочь под масштаб детали — параметром `minSegment`.** SVG рисуют в своём габарите (сотня
|
||||
условных единиц), и его скругления после масштабирования превращаются в дуги по 0.02–0.5 мм;
|
||||
замыкающий `z` часто даёт ещё и сегмент нулевой длины. `chamfer_edge` по такому набору отвечает
|
||||
«катет больше длины N из M рёбер» — и это правда. Передай `sketch_create(minSegment=катет)` (тот же
|
||||
параметр есть у `sketch_update` и `fragment_create`), и та же фаска пройдёт с первой попытки;
|
||||
отчёт о выброшенном читай, а не пролистывай — `help(topic="contour-cleanup")`.
|
||||
|
||||
**Порядок для фаски по контуру логотипа — только такой, и он неочевиден:**
|
||||
|
||||
1. **чистка** порогом ≈ будущего катета (`minSegment`);
|
||||
2. **замер ЧИЩЕНОГО силуэта** — `sketch_measure_thickness(entitiesFile, minSegment=тот же порог)`;
|
||||
3. **катет по узкому месту** чищеного силуэта: `c ≤ (узкое_место − 2·w)/2`, где `w` — ширина нити.
|
||||
|
||||
Менять шаги местами нельзя: **чистка СУЖАЕТ узкое место**. Она заменяет скругление острым углом —
|
||||
в выпуклом углу это добавляет материал (габарит подрастает), а в вогнутом срезает его, и именно
|
||||
вогнутые углы образуют перемычки между штрихами. Сужение доходит до единиц процентов узкого места —
|
||||
этого хватает, чтобы катет, подобранный по нечищеному контуру, перестал проходить свой же критерий.
|
||||
Числа снимай на СВОЁМ контуре: они принадлежат рисунку, а не приёму.
|
||||
|
||||
- **Ширину штриха и узкое место меряй инструментом, а не глазом** — `sketch_measure_thickness`
|
||||
ничего не строит и документа не требует, поэтому зовётся ДО эскиза
|
||||
(`help(topic="silhouette-thickness")`). От этих чисел зависит, останется ли что-то от рисунка
|
||||
после фаски и напечатается ли он вообще; шаг растра в ответе — точность округления катета.
|
||||
|
||||
## Подгонка ширины и кегля
|
||||
|
||||
@@ -61,7 +116,11 @@
|
||||
- **Толщина каймы — ещё и параметр стыковки блоков.** Кайма опускает силуэт надписи ниже её
|
||||
глифов на `t`, и именно это перекрытие с плашкой держит деталь одним телом. Считай так: низ
|
||||
каймы = низ глифов − t, и он должен зайти на плашку хотя бы на несколько десятых. Проверка —
|
||||
сводка «Тел:» в ответе самого `primitive(union)`.
|
||||
сводка «Тел:» в ответе самого `primitive(union)`: у примитивов она надёжна, потому что сервер
|
||||
сам сверяет объём до и после и отвергает объединение, ничего не давшее. **У `loft`/`sweep` этой
|
||||
сводке верить нельзя** — там она однажды напечатала «Тел: 1», когда тел было два (см. основной
|
||||
навык, п. «Ответ мутирующей операции»); в сомнительном случае считай тела
|
||||
`describe_model(sections="bodies")`.
|
||||
- **Кайма вокруг ПРЯМОУГОЛЬНОЙ плашки — вторым примитивом, а не тонкой стенкой.** Стенка обходит
|
||||
контуры эскиза, а плашка по playbook'у строится `primitive`, и каймы у неё не появится. Клади под
|
||||
неё второй блок на `2·t` больше и на высоту подложки (85 × 13.5 × 2 под плашкой 82 × 10.5 × 3) —
|
||||
@@ -89,16 +148,15 @@
|
||||
до нужной части силуэта помогает `minY`/`maxY`). **Порядок «сначала скругления углов, потом фаска»
|
||||
работает** — дуги от R0.5 фаске не мешают. В отборе встречается тип `other` (у сложных кривых) —
|
||||
он тоже принимается параметром `type`.
|
||||
- **Отказ фаски на НЕЧИЩЕНОМ контуре — не повод уменьшать катет: попробуй УВЕЛИЧИТЬ.** Успех
|
||||
немонотонен по размеру. На контуре логотипа (54 ребра низа, острые клинья между элементами)
|
||||
`chamfer_edge` отказывает при 0.4, 0.5, 0.6 и 0.7 и проходит при **0.8** — проверено подряд,
|
||||
с `rebuild` между попытками и на неизменных индексах рёбер. Похоже, малый катет оставляет в остром
|
||||
клине вырожденный «нос», который КОМПАС сшить не может, а большой срезает остриё целиком.
|
||||
**Но это верно ТОЛЬКО пока контур не почищен**, и полагаться на такой подбор не нужно: правильное
|
||||
лечение — `minSegment` (см. SKILL.md §«Надписи, логотипы и рельеф»), а не перебор катета.
|
||||
Замер на том же логотипе: почищенный порогом 0.5 контур (34 примитива) фаску **0.5 принимает**,
|
||||
а эталонные **0.8 отвергает** — рабочий диапазон катета сдвигается ВНИЗ вместе с узким местом
|
||||
(1.98 → 1.82 мм). После чистки совет «попробуй увеличить» уже вреден.
|
||||
- **Отказ фаски на НЕЧИЩЕНОМ контуре — не повод уменьшать катет: успех немонотонен по размеру.**
|
||||
На контуре с острыми клиньями между элементами `chamfer_edge` отказывает на нескольких катетах
|
||||
подряд и проходит на большем — проверено подряд, с `rebuild` между попытками и на неизменных
|
||||
индексах рёбер. Похоже, малый катет оставляет в остром клине вырожденный «нос», который КОМПАС
|
||||
сшить не может, а большой срезает остриё целиком. **Но перебирать катет не надо**: правильное
|
||||
лечение — `minSegment` (см. SKILL.md §«Надписи, логотипы и рельеф»). После чистки совет «попробуй
|
||||
увеличить» становится вреден: рабочий диапазон катета сдвигается ВНИЗ вместе с узким местом, и
|
||||
катет, проходивший на нечищеном контуре, чищеный отвергает. Не переносите подобранное значение
|
||||
между состояниями контура — оно к ним привязано.
|
||||
Прежняя формулировка добавляла «исключение самых коротких рёбер картину не меняет, то есть дело
|
||||
не в них» — вывод неверен: исключённое из `edgeIndices` ребро остаётся в теле, и это не то же
|
||||
самое, что убрать сегмент из контура. Убранный из контура — меняет.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: kompas-fdm-design
|
||||
description: >
|
||||
Методика проектирования деталей под FDM/FFF 3D-печать в КОМПАС-3D через MCP-сервер плагина:
|
||||
правила DFM (нависания и угол θ_max, толщины стенок n·w, отверстия и teardrop,
|
||||
правила DFM (нависания и угол θ_max, толщины стенок n·w, горизонтальные отверстия,
|
||||
посадки/зазоры, ориентация под прочность, elephant foot, бобышки/инсёрты/защёлки) ПЛЮС
|
||||
лёгкая самопроверка геометрии инструментами осмотра. Используй, когда задача — спроектировать
|
||||
или ДОВЕСТИ деталь, чтобы она хорошо ПЕЧАТАЛАСЬ на FDM. Триггеры: «сделай деталь
|
||||
@@ -42,7 +42,9 @@ description: >
|
||||
- **`θ_max` = предельный угол самонесущей поверхности ОТ ВЕРТИКАЛИ.** `θ_max ≈ arctan(w/2h)`
|
||||
(≈45° при `w`=0.4, `h`=0.2). **Дефолт 45°** (PLA, хороший обдув); **40°** для PETG/ABS
|
||||
(эмпирическая поправка на провис, не вывод формулы) или для толстого слоя (`h≥0.3` → формула
|
||||
даёт ~34°). Нависания, teardrop, фаски, зенковки берут угол из `θ_max`.
|
||||
даёт ~34°). Нависания, фаски, зенковки берут угол из `θ_max`. **Угол, заданный постановкой,
|
||||
главнее дефолта материала:** ТЗ назвало 45° для PETG — работай с 45° и назови расхождение с
|
||||
дефолтом 40° в допущениях, а не выбирай молча.
|
||||
- **Материал** (PLA / PETG / ABS) — модификатор зазоров/мостов/коробления/`θ_max`. См.
|
||||
`references/fdm-rules.md`.
|
||||
|
||||
@@ -51,10 +53,15 @@ description: >
|
||||
## Два правила (соблюдай всегда)
|
||||
|
||||
**1. Ориентация печати — первое проектное решение.**
|
||||
- **Спроси у пользователя** (если не задано): главное направление рабочей нагрузки и
|
||||
косметические/критичные грани. **Путь нагрузки из геометрии не выводится** — его задаёт задача.
|
||||
- **Путь нагрузки и косметические грани из геометрии не выводятся** — их задаёт задача. Спроси
|
||||
пользователя, **если есть кого спрашивать**; работаешь автономно (субагент, пакетный прогон) —
|
||||
выведи из постановки: что деталь держит, куда смотрит рабочая поверхность, чем она крепится.
|
||||
Выведенное — **запиши допущением** в ответ («принято: нагрузка — вес камеры 150 г вниз на плече
|
||||
53 мм; косметика не задана»), чтобы человек увидел, что именно ты предположил. Молчаливое
|
||||
«спросить некого» — не повод пропустить решение об ориентации: без него все дальнейшие правила
|
||||
повисают.
|
||||
- Реши постановку на стол (ось Z = рост слоёв). От неё зависит: где нависания; куда смотрят
|
||||
отверстия (вертикальные → компенсация Ø; горизонтальные → teardrop); путь нагрузки (**держи в
|
||||
отверстия (вертикальные → компенсация Ø; горизонтальные → по возможности развернуть вертикально); путь нагрузки (**держи в
|
||||
XY**; Z-сжатие можно, Z-растяжение/срез — нет); плоскости сопряжения (на XY-гранях); «лесенка» на
|
||||
наклонных функциональных поверхностях; если поддержки неизбежны — чтобы опорные грани были
|
||||
некритичными/скрытыми.
|
||||
@@ -65,47 +72,163 @@ description: >
|
||||
**FDM-чек-лист** (деталь *печатнопригодна*) — разные проверки. **Гео-аудит
|
||||
эвристический и не доказывает печатнопригодность** (не ловит путь нагрузки/анизотропию).
|
||||
|
||||
## Ориентация: когда три требования не сходятся
|
||||
|
||||
У консольной детали (кронштейн, полка, держатель) требования правила 1 — **нагрузка в XY**,
|
||||
**нависания ≤ `θ_max`**, **опорная площадка** — одновременно невыполнимы. Постоянного приоритета у
|
||||
них нет: он решается ЧИСЛОМ, и число считается за две минуты.
|
||||
|
||||
**Прикидка «прочность против ориентации».** Напряжение в корневом сечении против межслойной
|
||||
прочности — то есть против той самой величины, ради которой требуют «нагрузку в XY»:
|
||||
|
||||
1. `M = F·L` — момент в корне: `F = m·g` (Н), `L` — плечо до корневого сечения (мм) → Н·мм.
|
||||
2. `W = b·h²/6` — момент сопротивления прямоугольного сечения (`h` — размер В ПЛОСКОСТИ изгиба), мм³.
|
||||
Размеры сечения бери `describe_model(sections="box")` или `measure` по граням, а не из головы.
|
||||
3. `σ = M/W` (Н/мм² = МПа).
|
||||
4. Порог — межслойная прочность: доля от XY-прочности по §6 `fdm-rules.md`, для **PLA ~20–30 МПа**
|
||||
(PETG ~15–25, ABS ~8–15).
|
||||
|
||||
**Сечение на пути нагрузки не одно.** Момент проходит через КАЖДОЕ сечение от точки приложения до
|
||||
опоры: корень стойки, место, где она выходит из основания, тонкие ноги основания, перемычку у
|
||||
крепежа. Считай прикидку для всех и бери худшее — замер на кронштейне: корень стойки дал запас 32×,
|
||||
а ноги основания толщиной 4 мм под тот же момент — 3.6×. Самое тонкое место по пути, а не самое
|
||||
очевидное, и решает ориентацию.
|
||||
|
||||
**Точность прикидки — ПОРЯДОК, и в узкой полосе этого мало.** `W = b·h²/6` — это сплошное сечение,
|
||||
а печатная деталь сплошной не бывает: тот же навык требует стенки `n·w` и оставляет заполнение
|
||||
по умолчанию, так что настоящий момент сопротивления корневого сечения заметно ниже габаритного
|
||||
(у оболочки в три периметра на сечении 34×24 — примерно вдвое). Пока запас идёт порядками, это
|
||||
не мешает; в полосе **<3×**, где число и решает, погрешность метода равна ширине полосы. Поэтому:
|
||||
при запасе <3× пересчитайте `W` по фактическому сечению (оболочка `n·w` + заполнение) либо просто
|
||||
возьмите `W` вдвое меньше габаритного и посмотрите, в какой строке таблицы окажетесь.
|
||||
`W` и `I` СПЛОШНОГО фактического сечения (с отверстиями, скруглениями, карманами) не считайте по
|
||||
эскизу — их отдаёт `measure_section(plane, offset)` прямо с построенной детали
|
||||
(`help(topic="section-properties")`); поправка на оболочку и заполнение остаётся вашей.
|
||||
|
||||
| Запас `σ_меж/σ` | Что делать |
|
||||
|---|---|
|
||||
| **< 3×** | «Нагрузка в XY» — жёсткое требование, ориентацию выбирает оно; нависания лечим поддержками, площадку — фланцем, вплоть до разбиения детали (§13) |
|
||||
| **3–10×** | Держать XY, если это не стоит поддержек на функциональных гранях; несущее сечение поднять (§6: ×2 при неизбежной Z-нагрузке) |
|
||||
| **≥ 10×** | Требование СНИМАЕТСЯ — «слои на отрыв» здесь не размерный случай. Ориентацию выбирай по печати: сначала нависания, затем опорная площадка и устойчивость |
|
||||
|
||||
**Пример расчёта** (числа условные — у своей детали бери свои, из постановки и замеров): 150 г на
|
||||
плече 50 мм → `M = 0.150·9.81·50 ≈ 74 Н·мм`; сечение 30×20 → `W = 30·20²/6 = 2·10³ мм³`;
|
||||
`σ ≈ 37 кПа` против ~30 МПа межслойной PLA — запас **три порядка**. Слои тогда не решают ничего, и
|
||||
постановку выбирают по нависаниям, а не по прочности.
|
||||
Без этой прикидки правило «нагрузка в XY» читается как запрет и уводит в худшую по печати ориентацию.
|
||||
|
||||
**Постановки перебирают по граням габарита**, их немного: у плоско-изогнутой детали — две «плашмя»
|
||||
(широкой гранью вниз, посадочной гранью вниз) и одна «стоя» (корневым торцом вниз). Выпиши для
|
||||
каждой три числа — площадь нависающих граней, площадь опорного пятна и `σ` — и выбор перестанет
|
||||
быть спором вкусов. «Стоя» обычно выигрывает по нависаниям и проигрывает по устойчивости; её
|
||||
проверяют отдельно (гео-аудит, проверка центра масс).
|
||||
|
||||
## Рабочий цикл
|
||||
|
||||
1. **Калибровка**: сопло→`w`; слой→`h`→`θ_max`; материал→поправки.
|
||||
2. **Ориентация** (правило 1): опрос (нагрузка/косметика) → постановка, ось слоёв, сопряжения,
|
||||
«лесенка», поддержки.
|
||||
2. **Ориентация** (правило 1 + §«когда три требования не сходятся»): нагрузка/косметика — опросом
|
||||
или допущением → перебор постановок с числами → ось слоёв, сопряжения, «лесенка», поддержки.
|
||||
3. **Правила эскиза/операции** (строй через `kompas-3d`): стенки `n·w`; нависания → скос под
|
||||
`θ_max`; горизонтальные отверстия → teardrop; вертикальные → компенсация Ø; фаска у основания;
|
||||
`θ_max`; горизонтальные отверстия → развернуть ось вертикально, мелкое оставить круглым
|
||||
(короткий мост), крупное — D-отверстие с плоским верхом (`references/fdm-rules.md` §3);
|
||||
вертикальные → компенсация Ø; фаска у основания;
|
||||
зазоры посадок (со знаком); заходные фаски; мин. элементы/текст; бобышки/инсёрты/защёлки.
|
||||
Числа — в `references/fdm-rules.md`.
|
||||
4. **Гео-аудит** (`references/geometry-audit.md`) — инструментами осмотра.
|
||||
5. **Предусловия экспорта**: единое тело/манифолд (`boolean_union` при необходимости) →
|
||||
5. **Предусловия выдачи**: единое тело/манифолд (`boolean` при необходимости) →
|
||||
построение чистое.
|
||||
6. **Чек-лист** → экспорт **через `export_model`**: слайсеру нужен `.stl`
|
||||
(`export_model(path="….stl")` — двоичная сетка), а `.step` остаётся для передачи модели в САПР.
|
||||
6. **Чек-лист** → выдача. Обменный файл кладите **только если о нём попросили**: модель самоценна,
|
||||
а нарезает её человек сам. Попросили — `export_model` (`.stl` — двоичная сетка для слайсера,
|
||||
`.step` — для передачи модели в другую САПР).
|
||||
|
||||
## Чек-лист печатнопригодности
|
||||
|
||||
- [ ] Направление нагрузки и косметические грани **получены от пользователя**; ориентация
|
||||
зафиксирована; нагрузка в XY (или Z только на сжатие); сопряжения на XY-гранях.
|
||||
- [ ] Направление нагрузки и косметические грани **получены от пользователя или выведены из
|
||||
постановки и записаны допущением**; ориентация выбрана числом (запас `σ_меж/σ`), а не по
|
||||
умолчанию; нагрузка в XY (или Z только на сжатие, или запас ≥10×); сопряжения на XY-гранях.
|
||||
- [ ] Стенки кратны `w` (≥2·w; несущие ≥3·w, т.е. 3 периметра); нет «не кратных `w`» (кроме
|
||||
функциональных).
|
||||
- [ ] Нет 90°-полок; нависания ≤`θ_max` или заменены скосами; мосты в пределах пролёта по короткой
|
||||
стороне (числа — `references/fdm-rules.md`); внутренним поддержкам — доступ.
|
||||
- [ ] Горизонтальные отверстия — teardrop/D (геометрия из `θ_max`); вертикальные — компенсация Ø;
|
||||
глухие — дно ≥2–3 мм.
|
||||
- [ ] Фаска у основания (elephant foot); внутренние углы ≥R0.5; опорная площадка есть.
|
||||
- [ ] Нет 90°-полок; нависания ≤`θ_max` или заменены скосами — отбор ровно в той форме, что в
|
||||
§«Гео-аудит»: `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, minZ=<Zmin+0.1>)`
|
||||
(дефолтный допуск 15° ловит только почти горизонтальные потолки, а без `minZ` в улов
|
||||
попадает опорное пятно, без `minArea` — микрогрань, которая нависанием быть не может);
|
||||
пролёт каждого моста **замерен** `measure`, а не прикинут, и
|
||||
укладывается в `references/fdm-rules.md` §2 по короткой стороне; внутренним поддержкам — доступ.
|
||||
- [ ] Горизонтальные отверстия — ось развёрнута вертикально, либо мелкое оставлено круглым, либо
|
||||
D-отверстие; пролёт потолка посчитан и укладывается в норму моста; посадочные — под
|
||||
рассверловку; вертикальные — компенсация Ø; глухие — дно ≥2–3 мм.
|
||||
- [ ] Фаска у основания (elephant foot); внутренние углы ≥R0.5; опорная площадка есть, и для
|
||||
высокой детали проверена устойчивость по §«Гео-аудит»: очертание пятна —
|
||||
`list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)`, проекция ЦМ
|
||||
(`describe_model(sections="mass")`) внутри этого прямоугольника, высота ЦМ над столом
|
||||
≲3× полуширины пятна в узком направлении.
|
||||
- [ ] Посадки по таблице со **знаком** (натяг — вычесть); допуск ±0.2 **НЕ** прибавлен к зазору;
|
||||
заходные фаски на сопряжениях.
|
||||
- [ ] Мин. элементы/текст ≥ порогов; аспект тонких выступов ≤4–5×.
|
||||
- [ ] Мин. элементы/текст ≥ порогов (у надписи проверен ШТРИХ, а не кегль: чертёжный шрифт даёт
|
||||
`h/14` и порога не берёт — `references/fdm-rules.md` §7); сторона грани под надпись выбрана
|
||||
так, чтобы она не вышла зеркальной (§10); аспект тонких выступов ≤4–5×.
|
||||
- [ ] Бобышки/инсёрты (бор отверстия ≤ OD инсёрта, ставить с Z-грани)/резьба/защёлки (изгиб в XY) по правилам.
|
||||
- [ ] Полости — дренаж/вент; критичные поверхности не под «лесенкой»/поддержкой.
|
||||
- [ ] Предусловия экспорта: единое тело/манифолд; построение чистое.
|
||||
|
||||
## Гео-аудит (кратко)
|
||||
|
||||
Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP:
|
||||
`describe_model` / `list_faces` / `list_faces(index=N)` (нависания по нормалям нижних граней; цилиндры с
|
||||
горизонтальной осью → нужен teardrop), `describe_model(sections="box")` (как ось слоёв соотносится с габаритом),
|
||||
`measure` (номиналы/зазоры), `describe_model(sections="bodies")` + чистое построение (единое тело). **Границы и методика —
|
||||
`references/geometry-audit.md`.** Аудит эвристический; истинная мин. толщина стенки и полный детект
|
||||
криволинейных нависаний не решаются — это **не приговор и не доказательство печатнопригодности**.
|
||||
Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP — вызовами,
|
||||
а не пожеланиями:
|
||||
|
||||
- **Цилиндры, конусы и торы этот отбор не видит:** нормаль кривой грани берётся в её центре, и у
|
||||
горизонтального цилиндра она горизонтальна. Их проверяй отдельно: `list_faces(type=cylinder|cone)`
|
||||
→ ось (`axis`) горизонтальна — у цилиндра нижняя половина потолка нависает (отверстие — §3
|
||||
`references/fdm-rules.md`), у конуса угол нижней образующей к столу считай из угла конуса.
|
||||
- **Нависания одним отбором:** `list_faces(normal="0,0,-1", normalTolerance=90−θ_max,
|
||||
minZ=<Zmin+0.1>)` — всё вернувшееся кандидаты в нависания, и тем хуже, чем ближе нормаль
|
||||
к чистому −Z (горизонтальный потолок). При дефолтном `θ_max`=45° допуск равен 45 — это совпадение
|
||||
чисел, а не тождество: для PETG с `θ_max`=40° допуск **50**.
|
||||
**`minZ` тут не украшение, а условие правильности.** Отбор по нормали ЗНАКОВЫЙ, а у грани,
|
||||
лежащей на столе, внешняя нормаль равна ровно (0, 0, −1) — она проходит при ЛЮБОМ допуске и
|
||||
выглядит САМЫМ страшным нависанием, хотя это опорное пятно. Замер на кронштейне: тот же отбор
|
||||
без `minZ` (допуск 45°) вернул девять граней, и наибольшая из них — 515.44 мм² с центром ровно
|
||||
на `Zmin` (−50.50) — была пятном первого слоя. Первый слой печатается по столу и нависанием не
|
||||
бывает: отсекайте его окном, `Zmin` берите из `describe_model(sections="box")`.
|
||||
**`minArea` — вторая половина того же отбора.** Угол наклона грани — критерий для ПРОТЯЖЁННОГО
|
||||
нависания; на грани в единицы мм² он не значит ничего, потому что перекрыть надо не угол, а
|
||||
пролёт. Замер: крыша отверстия Ø6, срезанная касательными под 22.5° к горизонтали, приходит в
|
||||
улов как нарушение (нависание 67.5° при пороге 45°) — при площади 2.84 мм² и пролёте 2.30 мм,
|
||||
который печатается заведомо. Ставьте `minArea` порядка 5–10 мм², а всё мелкое, что всё же
|
||||
хотите проверить, судите пролётом (`measure`), а не углом: иначе аудит гонит на редизайн там,
|
||||
где всё в порядке.
|
||||
Дальше `list_faces(index=N)` по подозрительным; цилиндр с горизонтальной осью → проверить пролёт потолка (§3 правил).
|
||||
- **Пролёт моста меряют, а не считают по эскизу:** `measure(kind1="face", index1=…, kind2="face",
|
||||
index2=…)` между ВНУТРЕННИМИ гранями опор (замер: 49.0 мм между стойками). Сравнивать с §2
|
||||
`fdm-rules.md`: 49 мм при потолке PLA 15–25 мм — это редизайн, а не «как-нибудь напечатается».
|
||||
- **Устойчивость высокой печати** — самая дешёвая проверка из всех и единственная, которой нет
|
||||
больше нигде, но стоит она ТРЁХ вызовов, а не одного, и площади пятна для неё НЕ хватает:
|
||||
`list_faces` отдаёт по грани площадь, нормаль и центр — ни границ, ни полуширины из них не
|
||||
выводится. Очертание пятна даёт `list_edges`: он печатает координаты концов рёбер, а окно по Z
|
||||
оставляет только рёбра первого слоя.
|
||||
1. `describe_model(sections="box")` → `Zmin`.
|
||||
2. `describe_model(sections="mass")` → центр масс в мировых координатах (даром).
|
||||
3. `list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)` → концы рёбер пятна; их разброс по X и по Y и
|
||||
есть прямоугольник пятна, а половина меньшей стороны — полуширина в узком направлении.
|
||||
У КРУГЛОГО пятна так не выйдет: у замкнутой окружности концы совпадают, разброс схлопывается
|
||||
в точку. Тогда полуширина — радиус, и берут его `list_faces(index=N)` (у грани печатается
|
||||
радиус) или из длины ребра (`πD`).
|
||||
|
||||
Проверок две: проекция ЦМ `(x, y)` обязана лежать **внутри** этого прямоугольника (у консольной
|
||||
детали «стоя» она легко уходит за него — деталь падает недопечатанной), и высота ЦМ **над столом**
|
||||
(`z_ЦМ − Zmin`) ≲3× полуширины (эвристика; выше — интегральный фланец §5 или разбиение §13).
|
||||
**Пример** (условные числа): габарит `Z −50…180`, ЦМ `(0, 5, 57)`;
|
||||
`list_edges(minZ=−51, maxZ=−49)` вернул четыре ребра — `X −50…50`, `Y 0…8`, то есть
|
||||
пятно 100 × 8 мм. Проекция ЦМ (0, 5) внутри прямоугольника — первая проверка пройдена;
|
||||
высота ЦМ над столом 57 − (−50) = **107 мм** при полуширине узкого направления **4 мм**,
|
||||
это **27×** при пороге 3× — вторая провалена. Сработало именно второе число, и без очертания
|
||||
пятна взять его было неоткуда.
|
||||
- **Тело, габарит, номиналы:** `describe_model(sections="bodies")` + чистое построение (единое
|
||||
тело), `describe_model(sections="box")` (как ось слоёв соотносится с габаритом), `measure`.
|
||||
|
||||
**Границы и методика — `references/geometry-audit.md`.** Аудит эвристический; истинная мин. толщина
|
||||
стенки и полный детект криволинейных нависаний не решаются — это **не приговор и не доказательство
|
||||
печатнопригодности**.
|
||||
|
||||
**Просвет канала и толщину перемычки спрашивают, а не считают.** `measure(kind1="body", index1=0,
|
||||
kind2="body", index2=1)` даёт минимальное расстояние между телами целиком — не нужно угадывать, какие
|
||||
|
||||
@@ -36,12 +36,17 @@
|
||||
- **Вертикальные (ось ∥ Z)** печатаются уже номинала → **увеличить диаметр модели** (радиус на
|
||||
половину): **+0.2 мм (Ø<4)**, **+0.2–0.3 мм (Ø 4–10)**, **+0.1–0.2 мм (Ø>10)**; калибровать,
|
||||
критичные — рассверливать.
|
||||
- **Горизонтальные (ось в XY)** → **teardrop** или **D-отверстие** (плоский верх). Мин. Ø **2 мм**.
|
||||
Круглая часть тоже печатается уже → **+0.1–0.2 мм** к её Ø.
|
||||
- **Геометрия teardrop:** боковины касательны окружности под углом `θ_max` к вертикали (с двух
|
||||
сторон), сходятся в вершине на вертикальной оси. Высота вершины над центром = **`r / sin θ_max`**;
|
||||
включённый угол при вершине = **`2·θ_max`**. При `θ_max`=45° → `r/sin45° = √2·r ≈ 1.414·r` над
|
||||
центром (= **0.414·r над верхом окружности**), угол 90°. Низ — оставшаяся дуга окружности.
|
||||
- **Горизонтальные (ось в XY)** — потолок отверстия печатается нависанием. По порядку предпочтения:
|
||||
1. **Развернуть деталь** так, чтобы ось отверстия стала вертикальной (∥ Z), — если это не спорит
|
||||
с прочностью по слоям (§«Ориентация»).
|
||||
2. **Мелкое отверстие (Ø ≤ ~6 мм) — оставить круглым.** Потолок — короткий мост в пару
|
||||
миллиметров, FDM печатает его без поддержек; круглая часть печатается уже → **+0.1–0.2 мм** к Ø.
|
||||
3. **D-отверстие** — плоский верх: хорда на высоте `r·cos φ` над центром превращает потолок в мост
|
||||
шириной `2r·sin φ`, материал над хордой остаётся. Контур выреза — ЗАМКНУТЫЙ: дуга окружности
|
||||
снизу от одного конца хорды до другого (`arc3points` по точкам хорды и низу) плюс сама хорда
|
||||
отрезком. Дополнительный вырез поверх круглого отверстия D-формы не даёт — он только
|
||||
расширяет отверстие. Мост держи **≤ 5–10 мм**.
|
||||
Мин. Ø **2 мм**. Посадочные отверстия (вал, подшипник, штифт) после печати рассверливать.
|
||||
- **Глухое отверстие:** дно = внутренний мост → **толщина дна ≥2–3 мм** или купольное/
|
||||
вентилируемое. Сквозные предпочтительнее.
|
||||
- **Отступ от края** — через остаточную перемычку: стенка между отверстием и краем **≥2–3·w**
|
||||
@@ -73,6 +78,9 @@
|
||||
## 6. Ориентация и прочность
|
||||
- **Z (межслойная) прочность от XY:** PLA ~40–55%, PETG ~35–50%, **ABS ~20–35% (выброс)**. Несущую
|
||||
нагрузку — в **XY (вдоль слоёв)**.
|
||||
- **В абсолютных числах** (нужны, чтобы посчитать запас — SKILL.md §«Ориентация: когда три
|
||||
требования не сходятся»): XY на разрыв PLA ~50–60 МПа, PETG ~45–50, ABS ~35–40 ⇒ межслойная
|
||||
**PLA ~20–30, PETG ~15–25, ABS ~8–15 МПа**. Порядок величины, не паспорт конкретного филамента.
|
||||
- **Z-сжатие допустимо** (слои в сжатии не расслаиваются); избегать **Z-растяжения и Z-среза**.
|
||||
- Изгиб: слои в растяжении/сжатии, не на срез по линии слоя.
|
||||
- Z-нагрузка неизбежна → **увеличить несущее сечение** ~×2 относительно XY-расчёта.
|
||||
@@ -84,6 +92,13 @@
|
||||
- **Выпуклый** текст: штрих **≥0.5 мм**, высота **≥2·h (~0.4 мм)**, sans-serif bold.
|
||||
- **Гравированный** текст: штрих **≥2·w (~0.8–0.9 мм)** (нужно ≥2 периметра; 0.6 мм не влезает),
|
||||
глубина **≥2·h (~0.4 мм)**. (pt не используем — геометрия в мм.)
|
||||
- **Штрих задаёт ШРИФТ, а не кегль, и чертёжные шрифты под печать не годятся.** По ГОСТ 2.304
|
||||
толщина линии чертёжного шрифта равна `h/14`: кегль 8 даёт 0.57 мм — полторы ширины сопла, то
|
||||
есть ниже порога 2·w. Такой шрифт берёт порог только с кегля ~13 мм, а уверенно читаемые 3·w —
|
||||
с ~18 мм. У жирного гротеска штрих ≈ `h/4.5` (Arial Black при кегле 10 → ~2.2 мм), и порог
|
||||
выполняется с запасом уже на кегле 4–5 мм. Замер: «2» кеглем 8 шрифтом GOST type A на
|
||||
вертикальной стенке не читается вовсе; тот же символ кеглем 10 шрифтом Arial Black читается
|
||||
издалека. Маркировку набирайте жирным sans-serif и проверяйте штрих, а не высоту.
|
||||
|
||||
## 8. «Лесенка» (staircase) — критерий ориентации
|
||||
- Наклонные/криволинейные поверхности дают ступени: глубина ≈ **`h / tan(α)`** (α — угол от
|
||||
@@ -107,6 +122,13 @@
|
||||
верхнего слоя (там видны швы и «лесенка»). Тогда деталь и моделируют в этой ориентации — лицом
|
||||
к XOY, — а несимметричный рисунок (логотип, текст) **зеркалят**: на лицевую грань смотрят
|
||||
со стороны −Z. Проверка — снимок со стороны лица (`model_snapshot(view=rear)` для эскиза на XOY).
|
||||
- **Зеркалит не только лицо на столе — зеркалит ЛЮБАЯ грань, обращённая против нормали эскиза.**
|
||||
Надпись читается с той стороны, куда смотрит нормаль плоскости: XOY → **+Z**, XOZ → **+Y**,
|
||||
YOZ → **−X** (нормаль YOZ уходит в МИНУС X — тот же замер, что разворачивает на ней выдавливание).
|
||||
Значит гравировка по эскизу на YOZ, положенная на щеку с бОльшим X, выйдет зеркальной, а на
|
||||
щеку X=0 — правильной. Замер: цифра на щеке X=20.4 читалась зеркально при ЛЮБОМ `angle`; тот же
|
||||
эскиз, перенесённый на X=0, встал верно. **Поворотом это не лечится** — `angle` вращает, а не
|
||||
отражает; лечится выбором грани (или зеркальным контуром).
|
||||
- **Фаска по лицевому контуру — это ещё и размер первого слоя.** При 45° она сжимает силуэт лица
|
||||
на катет `c` по всему периметру, поэтому её потолок задаёт не эстетика, а то, что останется:
|
||||
`ширина_штриха − 2c ≥ 2·w`. У широкого рисунка (штрих ~10 мм) ограничением становится толщина
|
||||
@@ -118,24 +140,19 @@
|
||||
вписанную окружность, узкое место с координатами и таблицу «офсет `c` → на сколько кусков
|
||||
распалось лицо» — ничего не строя.
|
||||
- **Узкое место зависит от СОСТОЯНИЯ контура, поэтому порядок такой: чистка → замер чищеного →
|
||||
катет.** Замеры на обводке логотипа шириной 105 мм (штрих по наибольшей вписанной 11.5 мм):
|
||||
|
||||
| контур | узкое место | лицо распадается при |
|
||||
|---|---|---|
|
||||
| исходный, 54 примитива | 1.98 мм | c = 0.99 |
|
||||
| чищеный порогом 0.5, 34 примитива | **1.82 мм** | **c = 0.91** |
|
||||
|
||||
Чистка (`minSegment`) заменяет скругления острыми углами: в выпуклом углу это добавляет материал,
|
||||
в вогнутом — срезает, а перемычки между штрихами образованы как раз вогнутыми углами. То есть
|
||||
операция, которую делают РАДИ фаски, уменьшает допустимый катет. Мерьте после неё.
|
||||
- **Норматив катета — `c = stroke_min/2 − w`**, где `stroke_min` — узкое место, `w` — ширина нити.
|
||||
Он и есть решение неравенства `ширина − 2c ≥ 2w`. На том же логотипе: `1.82/2 − 0.4 = 0.51`,
|
||||
и в узком месте остаётся ровно 0.80 мм — два прохода сопла.
|
||||
**Осторожно с «эталонными» значениями из прошлых работ:** принятая когда-то на этом логотипе
|
||||
фаска 0.8 собственному правилу НЕ удовлетворяет (`1.82 − 1.6 = 0.22 мм` против нужных 0.8; даже
|
||||
по нечищеному контуру `1.98 − 1.6 = 0.38`). Она оставляет в узком месте одну нить экструзии —
|
||||
тело там сплошное, рвётся косметика лицевой грани, а это как раз та поверхность, ради которой
|
||||
деталь и кладут лицом на стол.
|
||||
катет.** Чистка (`minSegment`) заменяет скругления острыми углами: в выпуклом углу это добавляет
|
||||
материал, в вогнутом — срезает, а перемычки между штрихами образованы как раз вогнутыми углами.
|
||||
То есть операция, которую делают РАДИ фаски, уменьшает допустимый катет — на обводке логотипа это
|
||||
единицы процентов, и хватает, чтобы катет перестал проходить свой же критерий. Мерьте после неё,
|
||||
тем же порогом, каким будете строить.
|
||||
- **Норматив катета — `c = stroke_min/2 − w`**, где `stroke_min` — узкое место ЧИЩЕНОГО силуэта,
|
||||
`w` — ширина нити. Он и есть решение неравенства `ширина − 2c ≥ 2w`: в узком месте остаётся
|
||||
ровно `2w`, два прохода сопла. Считайте его на своём контуре — величина принадлежит рисунку.
|
||||
**Осторожно с «эталонными» значениями из прошлых работ:** катет, принятый когда-то на похожем
|
||||
знаке, своему же правилу обычно не удовлетворяет — он подбирался под другой рисунок, другой порог
|
||||
чистки или вовсе на глаз. Катет вдвое сверх норматива оставляет в узком месте одну нить экструзии:
|
||||
тело там сплошное, рвётся косметика лицевой грани — та самая поверхность, ради которой деталь и
|
||||
кладут лицом на стол. Сверьте нормативом, а не воспоминанием.
|
||||
- **Верхние рёбра — скругление** (R0.5–2.0); **но** радиус **> ~½ толщины стенки** сам даёт
|
||||
нависание > `θ_max` → тогда фаска/ступень.
|
||||
- **Внутренние углы — всегда скругление ≥R0.5**.
|
||||
|
||||
@@ -7,18 +7,45 @@
|
||||
|
||||
| Проверка | Как | Статус |
|
||||
|---|---|---|
|
||||
| Нависания (приближённо) | `list_faces`, затем `list_faces(index=N)`: для **нижних** граней угол поверхности от вертикали; > `θ_max` → флаг | ✅ плоские; ⚠️ криволинейные грубо |
|
||||
| Нависания (приближённо) | `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, minZ=<Zmin+0.1>)` — весь улов кандидаты; подробности `list_faces(index=N)` | ✅ плоские; ⚠️ криволинейные грубо |
|
||||
| Ориентация (геом. прокси) | `describe_model(sections="box")`: как ось слоёв соотносится с габаритом | ⚠️ длинная ось ≠ путь нагрузки |
|
||||
| Горизонтальные круглые отверстия | `list_faces(index=N)`: цилиндр с горизонтальной осью → «нужен teardrop» | ✅ |
|
||||
| Горизонтальные круглые отверстия | `list_faces(index=N)`: цилиндр с горизонтальной осью → пролёт потолка по `fdm-rules.md` §3 | ✅ |
|
||||
| Пролёт моста | `measure(kind1="face", index1=…, kind2="face", index2=…)` между внутренними гранями опор | ✅ |
|
||||
| Устойчивость высокой печати | `describe_model(sections="mass")` — центр масс; `list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)` — очертание опорного пятна по концам рёбер (площадь пятна из `list_faces` для этого не годится) | ✅ проекция ЦМ; ⚠️ порог по высоте — эвристика |
|
||||
| Номиналы / зазоры / габариты | `measure` между гранями; `describe_model(sections="box")` | ✅ |
|
||||
| Тело / манифолд перед выдачей | `describe_model(sections="bodies")` (одно тело?), итог проверки построения в ответе операции | ✅ |
|
||||
|
||||
**Почему допуск отбора нависаний равен `90−θ_max`.** `θ_max` меряют от вертикали, а отбор идёт по
|
||||
НОРМАЛИ: у поверхности, наклонённой на `θ` от вертикали, нормаль отстоит от −Z на `90−θ`. Значит
|
||||
нависание (`θ > θ_max`) — это в точности «нормаль ближе `90−θ_max` к −Z». При дефолтном `θ_max`=45°
|
||||
допуск численно равен 45, и это совпадение сбивает: для PETG с `θ_max`=40° правильный допуск **50**,
|
||||
а не 40.
|
||||
|
||||
**И почему у отбора нависаний обязано быть `minZ`.** Отбор по нормали ЗНАКОВЫЙ: грань проходит,
|
||||
если её нормаль отклонилась от заданного направления не более чем на допуск. У грани, лежащей на
|
||||
столе, внешняя нормаль равна ровно (0, 0, −1) — отклонение нулевое, значит она проходит при ЛЮБОМ
|
||||
допуске и по описанному критерию («тем хуже, чем ближе к чистому −Z») выглядит худшим нависанием
|
||||
детали. Замер: тот же отбор без `minZ` (допуск 45°) на кронштейне вернул девять граней, наибольшая —
|
||||
515.44 мм² с центром ровно на `Zmin` (−50.50) — и это опорное пятно, а не нависание.
|
||||
Нижняя граница окна (`minZ = Zmin + 0.1`, `Zmin` из `describe_model(sections="box")`) убирает
|
||||
первый слой из улова.
|
||||
|
||||
**Пролёт и пятно — числа, а не впечатления.** Замеры на кронштейне камеры: пролёт между стойками
|
||||
**49.0 мм** (потолок PLA по §2 `fdm-rules.md` — 15–25 мм, то есть редизайн); опорное пятно
|
||||
«стоя» — `list_edges(minZ=−51, maxZ=−50)` дал четыре ребра, `X −50.50…50.50`, `Y 0.00…8.00`, то
|
||||
есть **101 × 8 мм**, а ЦМ из `sections="mass"` — `(0.00, 4.93, 56.61)`: проекция внутри пятна, но
|
||||
высота ЦМ над столом **107.1 мм** против полуширины **4 мм** — 27× при пороге 3×. Ни то, ни другое
|
||||
не выводится из эскиза арифметикой — оба стоят одного вызова.
|
||||
|
||||
## Граница честности
|
||||
|
||||
- **Угол нависания** мерить в **той же конвенции, что fdm-rules.md** (от вертикали; нижняя грань с
|
||||
поверхностью > `θ_max` от вертикали = нависание) — не путать с углом нормали от горизонтали.
|
||||
- **Путь нагрузки агент НЕ выводит из габарита** — берёт из задачи/опроса (правило 1). Длинная ось
|
||||
≠ несущая.
|
||||
- **Путь нагрузки агент НЕ выводит из габарита** — берёт из задачи, из опроса, а работая автономно
|
||||
— из постановки, и тогда записывает допущением (правило 1). Длинная ось ≠ несущая.
|
||||
- **«Нагрузка в XY» — требование с порогом, а не догма.** Обязательность ориентации решает запас
|
||||
`σ_меж/σ` (SKILL.md, §«Ориентация: когда три требования не сходятся»); при запасе ≥10× выбор
|
||||
делают нависания и устойчивость, а не слои.
|
||||
- **Истинная мин. толщина стенки и полный детект криволинейных нависаний — не решаются** (нет
|
||||
thickness/overhang-солвера).
|
||||
- **Аудит эвристический и НЕ доказывает печатнопригодность** (не ловит анизотропию/путь нагрузки).
|
||||
@@ -29,5 +56,7 @@
|
||||
1. После построения, убедившись что оно чистое, — пройти таблицу выше сверху вниз.
|
||||
2. Каждый флаг — сверить с соответствующим правилом `fdm-rules.md` и решить: исправить геометрию
|
||||
или принять осознанно.
|
||||
3. Путь нагрузки и косметические грани взять из ответа пользователя (правило 1), не из габарита.
|
||||
4. Затем — чек-лист печатнопригодности (SKILL.md) → экспорт через `export_model` (`.stl` в слайсер).
|
||||
3. Путь нагрузки и косметические грани взять из ответа пользователя или из постановки (правило 1),
|
||||
не из габарита; ориентацию закрыть прикидкой `σ_меж/σ`.
|
||||
4. Затем — чек-лист печатнопригодности (SKILL.md) → выдача; обменный файл (`export_model`) —
|
||||
только если о нём просили.
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"tag": "v0.2.0",
|
||||
"sourceSha": "53ac64e24c4930b29dc2125cf1b488e8b5a1463e",
|
||||
"built": "2026-08-07T10:08:21Z"
|
||||
"version": "0.7.1",
|
||||
"tag": "v0.7.1",
|
||||
"sourceSha": "3029b17e8e1f52bf1bed08882fe368b7f0886b0a",
|
||||
"built": "2026-10-27T22:23:50Z"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user