4 Commits
64 changed files with 695 additions and 674 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
{ {
"name": "kompas", "name": "kompas",
"source": "./plugin", "source": "./plugin",
"description": "Управление КОМПАС-3D из Claude Code: 86 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", "category": "productivity",
"keywords": ["cad", "kompas", "3d", "step", "mcp", "fdm"] "keywords": ["cad", "kompas", "3d", "step", "mcp", "fdm"]
} }
+3 -3
View File
@@ -16,9 +16,9 @@ STEP/STL, осмотр и измерение модели — плюс два н
(`SDK\Samples\CSharp.zip`, каталог `Common`); при первом запуске они распаковываются (`SDK\Samples\CSharp.zip`, каталог `Common`); при первом запуске они распаковываются
в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`. Если SDK не установлен, укажите каталог в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`. Если SDK не установлен, укажите каталог
с этими сборками в переменной окружения `KOMPAS_INTEROP_DIR`; с этими сборками в переменной окружения `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), поэтому рантайм берётся с машины. поставляется framework-dependent (2,3 МБ вместо 34), поэтому рантайм берётся с машины.
Проверить: `dotnet --list-runtimes` должен показать `Microsoft.NETCore.App 8.x` или новее; Проверить: `dotnet --list-runtimes` должен показать `Microsoft.NETCore.App 10.x` или новее;
- чекаут и рабочие файлы — вне синхронизируемых папок OneDrive. - чекаут и рабочие файлы — вне синхронизируемых папок 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-3d`** | методика построения: порядок работы, выбор подхода, проверенные приёмы и ловушки |
| **Навык `kompas-fdm-design`** | проектирование под FDM/FFF-печать: нависания, толщины стенок, зазоры и посадки, ориентация, бобышки и защёлки | | **Навык `kompas-fdm-design`** | проектирование под FDM/FFF-печать: нависания, толщины стенок, зазоры и посадки, ориентация, бобышки и защёлки |
| **Команда `/kompas:doctor`** | диагностика установки | | **Команда `/kompas:doctor`** | диагностика установки |
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "kompas", "name": "kompas",
"displayName": "КОМПАС-3D", "displayName": "КОМПАС-3D",
"version": "0.3.0", "version": "0.7.0",
"description": "Управление КОМПАС-3D из Claude Code: детали, сборки, чертежи, STEP — через MCP-сервер", "description": "Управление КОМПАС-3D из Claude Code: детали, сборки, чертежи, STEP — через MCP-сервер",
"author": { "author": {
"name": "Shahovalov Mikhail", "name": "Shahovalov Mikhail",
+9 -2
View File
@@ -13,9 +13,9 @@
сервера не входят и берутся из установки (`SDK\Samples\CSharp.zip`, каталог `Common`). При первом сервера не входят и берутся из установки (`SDK\Samples\CSharp.zip`, каталог `Common`). При первом
запуске они распаковываются в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`; если SDK не установлен, запуске они распаковываются в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`; если SDK не установлен,
укажите каталог с этими сборками в переменной окружения `KOMPAS_INTEROP_DIR`; укажите каталог с этими сборками в переменной окружения `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` поставляется framework-dependent, рантайм берётся с машины. Проверка: `dotnet --list-runtimes`
показывает `Microsoft.NETCore.App 8.x` или новее; показывает `Microsoft.NETCore.App 10.x` или новее;
- чекаут репозитория и рабочие файлы — вне синхронизируемых папок OneDrive. - чекаут репозитория и рабочие файлы — вне синхронизируемых папок OneDrive.
## Установка ## Установка
@@ -38,6 +38,13 @@
Если инструменты остались прежними — `/reload-plugins`. Если инструменты остались прежними — `/reload-plugins`.
## Промпты и ресурсы
Сервер отдаёт готовые маршруты работы промптами — `part`, `import-edit-export`, `drawing`,
`assembly` — и они появляются в меню slash-команд Claude Code как `/kompas:part (MCP)` и т. д.
Справочник и сводка активной модели доступны ресурсами `kompas://help/<тема>` и
`kompas://active/summary`; агент читает их сам, а подстановка через @-упоминание зависит от клиента.
## Разработка сервера ## Разработка сервера
Переменная окружения `KOMPAS_MCP_EXE` подменяет поставленный бинарь своим: Переменная окружения `KOMPAS_MCP_EXE` подменяет поставленный бинарь своим:
+1 -1
View File
@@ -4,7 +4,7 @@ Codex не знает ни маркетплейсов, ни `${CLAUDE_PLUGIN_ROO
к каталогу плагина. к каталогу плагина.
1. Склонировать `https://git.shahovalov.ru/mikhail/kompas-plugin.git` — сервер лежит внутри, 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>` на абсолютный путь 2. Вставить `config.snippet.toml` в `~/.codex/config.toml`, заменив `<PLUGIN>` на абсолютный путь
к каталогу `plugin/` клона. Лаунчер `scripts/launch-kompas-mcp.ps1` — тот же, что у плагина к каталогу `plugin/` клона. Лаунчер `scripts/launch-kompas-mcp.ps1` — тот же, что у плагина
Claude Code. Claude Code.
+1 -1
View File
@@ -1,7 +1,7 @@
# Подключение к opencode # Подключение к opencode
1. Склонировать `https://git.shahovalov.ru/mikhail/kompas-plugin.git` — сервер лежит внутри, 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>` на абсолютный путь к 2. Слить `opencode.json` со своим конфигом opencode, заменив `<PLUGIN>` на абсолютный путь к
каталогу `plugin/` клона. Используется тот же лаунчер `scripts/launch-kompas-mcp.ps1`. каталогу `plugin/` клона. Используется тот же лаунчер `scripts/launch-kompas-mcp.ps1`.
3. Навыки: скопировать `plugin/skills/{kompas-3d,kompas-fdm-design}` в каталог навыков агента 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.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4 -3
View File
@@ -1,14 +1,15 @@
{ {
"runtimeOptions": { "runtimeOptions": {
"tfm": "net8.0", "tfm": "net10.0",
"rollForward": "LatestMajor", "rollForward": "LatestMajor",
"framework": { "framework": {
"name": "Microsoft.NETCore.App", "name": "Microsoft.NETCore.App",
"version": "8.0.0" "version": "10.0.0"
}, },
"configProperties": { "configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false, "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
"CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false
} }
} }
} }
+4 -3
View File
@@ -28,14 +28,15 @@ description: "Диагностика установки плагина КОМП
`/plugin update kompas@kompas-plugin`, затем `/reload-plugins`. `/plugin update kompas@kompas-plugin`, затем `/reload-plugins`.
4. **.NET Runtime.** Сервер поставляется framework-dependent, поэтому рантайм нужен на машине: 4. **.NET Runtime.** Сервер поставляется framework-dependent, поэтому рантайм нужен на машине:
`dotnet --list-runtimes` должен показать строку `Microsoft.NETCore.App 8.<любая>` или новее `dotnet --list-runtimes` должен показать строку `Microsoft.NETCore.App 10.<любая>` или новее
(x64). Ни одной подходящей строки или самой команды `dotnet` нет — это и есть причина сбоя (x64). Ни одной подходящей строки или самой команды `dotnet` нет — это и есть причина сбоя
пункта 3: попроси пользователя поставить .NET Runtime 8 или новее с пункта 3: попроси пользователя поставить .NET Runtime 10 или новее с
https://dotnet.microsoft.com/download/dotnet (нужен именно x64; Desktop Runtime не обязателен). https://dotnet.microsoft.com/download/dotnet (нужен именно x64; Desktop Runtime не обязателен).
5. **КОМПАС-3D установлен и, возможно, уже запущен.** Сервер подключается к КОМПАС лениво — не при 5. **КОМПАС-3D установлен и, возможно, уже запущен.** Сервер подключается к КОМПАС лениво — не при
старте MCP-сервера, а при первом вызове инструмента. Проверь двумя командами: старте 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` `Get-ChildItem 'HKLM:\SOFTWARE\Classes\KOMPAS.Application.5' -ErrorAction SilentlyContinue`
(зарегистрирован ли COM-класс, то есть установлен ли КОМПАС вообще). Запущен — сервер (зарегистрирован ли COM-класс, то есть установлен ли КОМПАС вообще). Запущен — сервер
присоединится к нему; не запущен, но зарегистрирован — попробует запустить новый экземпляр сам; присоединится к нему; не запущен, но зарегистрирован — попробует запустить новый экземпляр сам;
+1 -1
View File
@@ -40,7 +40,7 @@ catch {
# Самая частая причина здесь — отсутствующий .NET Runtime: сервер поставляется # Самая частая причина здесь — отсутствующий .NET Runtime: сервер поставляется
# framework-dependent, и без рантайма apphost падает именно тут. # framework-dependent, и без рантайма apphost падает именно тут.
[Console]::Error.WriteLine("kompas-mcp launcher: не удалось запустить сервер: $($_.Exception.Message)") [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 exit 1
} }
+90 -17
View File
@@ -5,9 +5,10 @@ description: >
модификация деталей, импорт/экспорт STEP, работа со сборками, осмотр геометрии модификация деталей, импорт/экспорт STEP, работа со сборками, осмотр геометрии
снимками и запросами. Используй ВСЕГДА, когда задача — что-то СДЕЛАТЬ в КОМПАС снимками и запросами. Используй ВСЕГДА, когда задача — что-то СДЕЛАТЬ в КОМПАС
через MCP-инструменты (создать/править деталь, импортировать STEP, разобрать через MCP-инструменты (создать/править деталь, импортировать STEP, разобрать
сборку, померить, отрендерить, экспортировать). Здесь — playbook'и и эвристики, сборку, померить, раскрасить, отрендерить, экспортировать). Здесь — playbook'и и эвристики,
проверенные на практике. Триггеры: «построй деталь в КОМПАС», «импортируй STEP», проверенные на практике. Триггеры: «построй деталь в КОМПАС», «импортируй STEP»,
«что в этой сборке», «нарасти/измени деталь», «экспортируй STEP», «сделай снимок модели». «что в этой сборке», «нарасти/измени деталь», «раскрась модель / выдели надпись цветом», «экспортируй STEP»,
«сделай снимок модели».
--- ---
# kompas-3d — методика управления КОМПАС-3D через MCP # kompas-3d — методика управления КОМПАС-3D через MCP
@@ -74,7 +75,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
и счётчик граней законно остаётся прежним. и счётчик граней законно остаётся прежним.
**Но обратное неверно: «Тел: 1» распад не опровергает.** Счётчик в сводке ОПАЗДЫВАЕТ. Замер **Но обратное неверно: «Тел: 1» распад не опровергает.** Счётчик в сводке ОПАЗДЫВАЕТ. Замер
(журнал операций кейса с хвостом по сечениям): `loft` построил второе тело и отчитался (журнал операций кейса с хвостом по сечениям): `loft` построил второе тело и отчитался
«Тел: 1», следом `mirror` — снова «Тел: 1», и только третья операция, `chamfer_edge`, напечатала «Тел: 1», следом `pattern(kind=mirror)` — снова «Тел: 1», и только третья операция, `chamfer_edge`, напечатала
«Тел: 2», хотя между ними ничего не создавалось. Три операции подряд шли по детали, объём «Тел: 2», хотя между ними ничего не создавалось. Три операции подряд шли по детали, объём
которой считал пересечение дважды. Поэтому «Тел: 2» — тревога, которой верят сразу, а «Тел: 1» — которой считал пересечение дважды. Поэтому «Тел: 2» — тревога, которой верят сразу, а «Тел: 1» —
не доказательство: там, где важно именно СРАСТАНИЕ (loft/sweep на грань, надпись, примитив не доказательство: там, где важно именно СРАСТАНИЕ (loft/sweep на грань, надпись, примитив
@@ -95,7 +96,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
`help(topic="build-verification")`. `help(topic="build-verification")`.
Отдельный `describe_model(sections=errors,bodies,mass)` после каждого шага не нужен. Он Отдельный `describe_model(sections=errors,bodies,mass)` после каждого шага не нужен. Он
возвращается, когда авто-проверку выключили (`set_auto_validate(false)` на тяжёлой модели, где возвращается, когда авто-проверку выключили (`kompas_connect(autoValidate=false)` на тяжёлой модели, где
проверка каждого шага тормозит): тогда `describe_model(sections=errors,bodies,mass)` вручную перед выдачей: одного проверка каждого шага тормозит): тогда `describe_model(sections=errors,bodies,mass)` вручную перед выдачей: одного
`errors` мало — распад детали на два тела показывает только раздел `bodies`. `errors` мало — распад детали на два тела показывает только раздел `bodies`.
@@ -116,8 +117,8 @@ variables | errors | components` (`sections` сужает и ответ, и об
## Инструменты: где искать каталог ## Инструменты: где искать каталог
Полный перечень 86 инструментов с параметрами — README плагина §«Инструменты» (единый источник Полный перечень инструментов с параметрами — `tools/list` самого MCP-сервера (единый источник
правды, держать вторую копию здесь не нужно) или `tools/list` самого MCP-сервера. Что известно про правды, держать вторую копию здесь не нужно). Что известно про
КОНКРЕТНЫЙ инструмент — `help(tool="extrude")`. Три сквозных свойства контракта, которые полезно КОНКРЕТНЫЙ инструмент — `help(tool="extrude")`. Три сквозных свойства контракта, которые полезно
держать в голове, а не искать заново на каждом инструменте: **размерный параметр принимает число ИЛИ выражение** (имя держать в голове, а не искать заново на каждом инструменте: **размерный параметр принимает число ИЛИ выражение** (имя
переменной/формулу — параметр сразу становится ведомым); **объект выбирается индексом** (надёжно) переменной/формулу — параметр сразу становится ведомым); **объект выбирается индексом** (надёжно)
@@ -152,6 +153,8 @@ variables | errors | components` (`sections` сужает и ответ, и об
| Переменное сечение: хвост, гребень, переход круга в квадрат | `loft` по сечениям на смещённых плоскостях (`mode=boss` приклеивает к телу) | | Переменное сечение: хвост, гребень, переход круга в квадрат | `loft` по сечениям на смещённых плоскостях (`mode=boss` приклеивает к телу) |
| Труба, поручень, кант по кривой | `sweep(profileSketchId, pathSketchId)` — профиль и траектория на разных плоскостях | | Труба, поручень, кант по кривой | `sweep(profileSketchId, pathSketchId)` — профиль и траектория на разных плоскостях |
| Тонкая стенка, ободок по контуру | эскиз + `extrude(thinThickness, thinSide)` | | Тонкая стенка, ободок по контуру | эскиз + `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")` |
Их **сочетают в одной детали**: корпусные объёмы — примитивами, сложные контуры — эскизами. Их **сочетают в одной детали**: корпусные объёмы — примитивами, сложные контуры — эскизами.
@@ -179,7 +182,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
причины, значит фаска выродилась в достройку: убери её `feature_delete`, пологому стыку она причины, значит фаска выродилась в достройку: убери её `feature_delete`, пологому стыку она
и не нужна. и не нужна.
- **`result=new` даёт ОТДЕЛЬНОЕ тело**, `subtract` мимо цели сервер ловит сам — и то и другое - **`result=new` даёт ОТДЕЛЬНОЕ тело**, `subtract` мимо цели сервер ловит сам — и то и другое
видно по сводке «Тел/объём» в ответе; при распаде зови `boolean_union`. видно по сводке «Тел/объём» в ответе; при распаде зови `boolean`.
- **Сужающуюся или изогнутую форму не набирай лесенкой из примитивов.** `primitive` не умеет - **Сужающуюся или изогнутую форму не набирай лесенкой из примитивов.** `primitive` не умеет
поворота, и «хвост» из десятка блоков со ступеньками — это обход отсутствующего инструмента, поворота, и «хвост» из десятка блоков со ступеньками — это обход отсутствующего инструмента,
а не решение: он и печатается хуже, и правится только целиком. Бери `loft` по 4–6 сечениям на а не решение: он и печатается хуже, и правится только целиком. Бери `loft` по 4–6 сечениям на
@@ -197,7 +200,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
Опорный сценарий построения, проверен end-to-end: Опорный сценарий построения, проверен end-to-end:
1. `kompas_connect` (+ `kompas_set_visible true`). **Работаешь не один — бери свой экземпляр:** 1. `kompas_connect` (+ `visible=true`). **Работаешь не один — бери свой экземпляр:**
`kompas_connect(instance="private")` (см. «Когда КОМПАС общий»). `kompas_connect(instance="private")` (см. «Когда КОМПАС общий»).
2. `document_create(type="part", name="…")` — наименование даём сразу, здесь оно ничего не стоит. 2. `document_create(type="part", name="…")` — наименование даём сразу, здесь оно ничего не стоит.
3. **Запиши замысел переменными** до первого эскиза (см. «Параметризация») и связывай каждый 3. **Запиши замысел переменными** до первого эскиза (см. «Параметризация») и связывай каждый
@@ -206,7 +209,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
5. `extrude` / `revolve` → прочитай итог проверки и сводку прямо в ответе (правило 2). 5. `extrude` / `revolve` → прочитай итог проверки и сводку прямо в ответе (правило 2).
6. Осмотр — структурно: `describe_model` (нужен кусок — `sections="box,mass"`). 6. Осмотр — структурно: `describe_model` (нужен кусок — `sections="box,mass"`).
7. Итерация «на грани»: `list_faces` → `sketch_create(faceIndex=N, entities=[…])` → операция. 7. Итерация «на грани»: `list_faces` → `sketch_create(faceIndex=N, entities=[…])` → операция.
8. **Задай материал, если смотришь на массу** — `set_part_material`: у нового документа стоит 8. **Задай материал, если смотришь на массу** — `set_part_info(material, density)`: у нового документа стоит
сталь 7.86, и МЦХ печатной детали завышена вшестеро; плотности ходовых материалов перечислены сталь 7.86, и МЦХ печатной детали завышена вшестеро; плотности ходовых материалов перечислены
в описании инструмента. в описании инструмента.
9. **Проверь, что деталь названа** (шаг 2 или `set_part_info`) — безликая «Деталь» уедет в штамп 9. **Проверь, что деталь названа** (шаг 2 или `set_part_info`) — безликая «Деталь» уедет в штамп
@@ -230,6 +233,27 @@ variables | errors | components` (`sections` сужает и ответ, и об
прямо говорит «⚠ НИЧЕГО НЕ ВЕДЁТ» в этом случае — не успех, хоть число и поменялось. прямо говорит «⚠ НИЧЕГО НЕ ВЕДЁТ» в этом случае — не успех, хоть число и поменялось.
- **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт»; - **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт»;
`delete_variable(unused=true)` не трогает справочные (`information`) и внешние. `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`), как сервер ловит промахи в формулах, справочные Полная методика — обязательные поля (`note`), как сервер ловит промахи в формулах, справочные
переменные `(ТЗ)` и порядок уборки — [reference/parametrization.md](reference/parametrization.md). переменные `(ТЗ)` и порядок уборки — [reference/parametrization.md](reference/parametrization.md).
@@ -277,6 +301,50 @@ variables | errors | components` (`sections` сужает и ответ, и об
Фрагмент (*.frw, самостоятельный файл переиспользуемого контура/чертежа) — Фрагмент (*.frw, самостоятельный файл переиспользуемого контура/чертежа) —
[reference/fragments.md](reference/fragments.md). [reference/fragments.md](reference/fragments.md).
## Раскраска: умеренно и по смыслу
Цвет — последний шаг, после геометрии: `set_appearance` её не трогает и в дереве узлов не
плодит. Задача раскраски — чтобы модель читалась с первого взгляда, а не чтобы она была пёстрой.
- **Одна основа, один-два акцента.** Деталь целиком — спокойный нейтральный цвет
(`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`.
Механизм, имена цветов и измеренные факты — `help(topic="appearance")`.
## Сборка: собрать своё ## Сборка: собрать своё
Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.** Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.**
@@ -315,7 +383,11 @@ STEP/импортом) — следующий раздел.
`extrude(mode=cut, forward=true)` режет ВНИЗ, в тело. То есть у выреза «прямое» — это внутрь `extrude(mode=cut, forward=true)` режет ВНИЗ, в тело. То есть у выреза «прямое» — это внутрь
материала. Оба умолчания делают то, чего обычно и хотят, но рассуждение «forward — это плюс материала. Оба умолчания делают то, чего обычно и хотят, но рассуждение «forward — это плюс
нормали» даст перевёрнутый карман. **Вырез, ушедший в пустоту, КОМПАС считает успехом** — нормали» даст перевёрнутый карман. **Вырез, ушедший в пустоту, КОМПАС считает успехом** —
дерево чистое, объём не изменился; ловит это только строка сверки в ответе. дерево чистое, объём не изменился; ловит это только строка сверки в ответе. Поэтому у
`extrude`/`revolve(mode=cut)` **не задавай `forward`, если сторона неочевидна**: сервер сам
переделает вырез, не убравший материала, в обратную сторону и скажет об этом в ответе.
Выбор работает, только если одна сторона пуста: эскиз ВНУТРИ материала (плоскость посреди вала)
режет в обе стороны — там `forward` задавай сам и сверяй объём.
- **На YOZ деталь растёт в МИНУС X, и туда же уезжает смещение плоскости.** Нормаль базовой - **На YOZ деталь растёт в МИНУС X, и туда же уезжает смещение плоскости.** Нормаль базовой
плоскости смотрит в плюс своей оси не всегда — замерено: XOY → +Z, XOZ → +Y, а **YOZ → −X**. плоскости смотрит в плюс своей оси не всегда — замерено: XOY → +Z, XOZ → +Y, а **YOZ → −X**.
Значит `extrude(forward=true)` по эскизу на YOZ кладёт материал в отрицательные X, а Значит `extrude(forward=true)` по эскизу на YOZ кладёт материал в отрицательные X, а
@@ -341,7 +413,7 @@ STEP/импортом) — следующий раздел.
Хендл — это НЕ индекс: `faceIndex`/`edgeIndices` из `list_faces`/`list_edges` и параметр Хендл — это НЕ индекс: `faceIndex`/`edgeIndices` из `list_faces`/`list_edges` и параметр
`feature` у `link_parameter`/`list_parameters` (имя или индекс узла дерева) остаются числовыми. `feature` у `link_parameter`/`list_parameters` (имя или индекс узла дерева) остаются числовыми.
`primitive` и `hole` тоже возвращают хендл (у `hole` — по одному на КАЖДОЕ отверстие серии), `primitive` и `hole` тоже возвращают хендл (у `hole` — по одному на КАЖДОЕ отверстие серии),
так что примитив и отверстие можно удалить `feature_delete` и размножить `pattern`/`mirror`. так что примитив и отверстие можно удалить `feature_delete` и размножить `pattern` (и `kind=mirror`).
Если ответ вместо хендла говорит «выдать не удалось» — операция построена, но адресовать её Если ответ вместо хендла говорит «выдать не удалось» — операция построена, но адресовать её
нечем: переставить её потом можно только пересборкой. нечем: переставить её потом можно только пересборкой.
- **Единицы — мм** (геометрия) и **кг** (масса). Локальные координаты эскиза ≠ мировые координаты - **Единицы — мм** (геометрия) и **кг** (масса). Локальные координаты эскиза ≠ мировые координаты
@@ -362,7 +434,7 @@ STEP/импортом) — следующий раздел.
сохранения. сохранения.
- **Строишь параллельно с кем-то — `instance="private"`** при первом `kompas_connect` (потом режим - **Строишь параллельно с кем-то — `instance="private"`** при первом `kompas_connect` (потом режим
не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_set_visible true` не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_connect(visible=true)`
покажет). покажет).
- **`shared` оставляй**, когда работа идёт на глазах у человека и ты единственный агент. - **`shared` оставляй**, когда работа идёт на глазах у человека и ты единственный агент.
- **Один файл в двух экземплярах не открыть** — второй получит его только на чтение: работу делите - **Один файл в двух экземплярах не открыть** — второй получит его только на чтение: работу делите
@@ -370,11 +442,12 @@ STEP/импортом) — следующий раздел.
## Открытые вопросы / границы ## Открытые вопросы / границы
- **Параметрика работает через параметры ОПЕРАЦИЙ, а не координаты ВНУТРИ эскиза** — сдвинуть - **Координата в точке — число или выражение (считается один раз), а форму контура ведут `dimensions`** с выражениями
контур переменной нельзя, только пересобрать эскиз (`sketch_update`). Но это ограничение уже (`help(topic="sketch-dimensions")`). Уже наложенный размер перепривязывается без пересборки:
границей: **плоскость** эскиза — обычный узел дерева с параметром «Расстояние», и она `link_parameter(feature=<узел эскиза>, parameter="v15")` — имя `vNN` есть в ответе
параметризуется как всё остальное. Планируй членение так, чтобы изменяемое задавалось параметром `sketch_create` и в `list_parameters` (у одноимённых «Линейный размер» — в скобках). Эскиз без
операции (глубина, радиус, габарит примитива) или положением плоскости, а не координатами точек. размеров переменной не двигается — только пересборкой (`sketch_update`); положение эскиза задаёт
**плоскость** — обычный узел с параметром «Расстояние».
- **2D покрыт вместе с разрезом и сечением.** Есть виды (с выбором набора, ориентации главного и - **2D покрыт вместе с разрезом и сечением.** Есть виды (с выбором набора, ориентации главного и
невидимых линий), разрез/сечение, листы, штамп, размеры с допусками, осевые, обозначения, невидимых линий), разрез/сечение, листы, штамп, размеры с допусками, осевые, обозначения,
техтребования, удаление и сдвиг объекта, вывод в растр — методика в §«Чертёж». Нет выносного техтребования, удаление и сдвиг объекта, вывод в растр — методика в §«Чертёж». Нет выносного
@@ -13,12 +13,12 @@
ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость
с наибольшей информацией. с наибольшей информацией.
2. **`drawing_set_sheet_format`** (формат до видов — иначе виды придётся двигать), при 2. **`drawing_set_sheet_format`** (формат до видов — иначе виды придётся двигать), при
необходимости `drawing_add_sheet` для второго листа. необходимости `drawing_set_sheet_format(add=true)` для второго листа.
3. **`drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…)`** — бери ровно те 3. **`drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…)`** — бери ровно те
проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. **Главный вид проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. **Главный вид
входит в набор сам**: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому `views=["top"]` входит в набор сам**: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому `views=["top"]`
даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими. даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими.
4. **Координаты — замером, а не формулой.** `drawing_get_view_info(viewNumber)` отдаёт паспорт вида 4. **Координаты — замером, а не формулой.** `describe_drawing(sections=view, viewNumber)` отдаёт паспорт вида
одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает
начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось
проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид
@@ -34,7 +34,7 @@
6. **Размеры**, `drawing_add_axis` (осевые и центровые), шероховатость, выноски, техтребования, 6. **Размеры**, `drawing_add_axis` (осевые и центровые), шероховатость, выноски, техтребования,
штамп. **Осевые сначала посмотри, потом добивай**: ассоциативные виды приходят со СВОИМИ штамп. **Осевые сначала посмотри, потом добивай**: ассоциативные виды приходят со СВОИМИ
центровыми и осевыми, которые КОМПАС ставит сам, и `drawing_add_axis` вслепую даёт дубли поверх центровыми и осевыми, которые КОМПАС ставит сам, и `drawing_add_axis` вслепую даёт дубли поверх
существующих. Сначала `list_drawing_objects(kind="axis"|"centreMarker", viewNumber=…)`. существующих. Сначала `describe_drawing(kind="axis"|"centreMarker", viewNumber=…)`.
7. **`drawing_export_image`** — посмотреть глазами. Пока картинки не было, чертёж не сдан. 7. **`drawing_export_image`** — посмотреть глазами. Пока картинки не было, чертёж не сдан.
## Разрез ## Разрез
@@ -48,16 +48,16 @@
стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к
штриховой линии не привязывают. штриховой линии не привязывают.
- **Веди линию с запасом за габарит** (плита 60 мм → от −40 до +40): линия по самому краю режет не - **Веди линию с запасом за габарит** (плита 60 мм → от −40 до +40): линия по самому краю режет не
всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `drawing_get_view_info`. всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `describe_drawing(sections=view)`.
- **Строй разрез, когда модель готова**: после правки детали перестраивается только ПЕРВЫЙ разрез - **Строй разрез, когда модель готова**: после правки детали перестраивается только ПЕРВЫЙ разрез
базового вида. Модель всё же изменилась — снеси разрезы и построй заново. базового вида. Модель всё же изменилась — снеси разрезы и построй заново.
- Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру. - Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру.
**Промах простановки лечится, а не остаётся навсегда.** Отката (undo) у чертежа нет, но **Промах простановки лечится, а не остаётся навсегда.** Отката (undo) у чертежа нет, но
`list_drawing_objects` показывает обозначения с индексами, `drawing_delete_object` убирает одно, а `describe_drawing` показывает обозначения с индексами, `drawing_delete(target=object)` убирает одно, а
`drawing_move_object` его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не `drawing_move_object` его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не
заменой размера на выноску. Так же правится и компоновка: `drawing_move_view` переставляет вид со заменой размера на выноску. Так же правится и компоновка: `drawing_move_view` переставляет вид со
всеми обозначениями, `drawing_add_view` доносит недостающую проекцию, `drawing_delete_view` убирает всеми обозначениями, `drawing_create_standard_views(views=[])` доносит недостающую проекцию, `drawing_delete(target=view)` убирает
лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления — лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления —
`help(topic="drawing-fixing")`. `help(topic="drawing-fixing")`.
@@ -27,6 +27,12 @@
`embodiment(action="set", target="L600", component=N)` и затем `rebuild`. Сопряжения при этом `embodiment(action="set", target="L600", component=N)` и затем `rebuild`. Сопряжения при этом
**сохраняются** — пересоздание вставки, наоборот, порвало бы их все. Какие исполнения есть у **сохраняются** — пересоздание вставки, наоборот, порвало бы их все. Какие исполнения есть у
конкретного экземпляра, показывает `describe_model(sections="embodiments", component=N)`. конкретного экземпляра, показывает `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")`: каждое исполнение в свой - **Выгнать всю линейку на печать** — `export_model(embodiment="all")`: каждое исполнение в свой
файл с суффиксом обозначения. файл с суффиксом обозначения.
- **После смены исполнения в собранном узле проверь сопряжения** (`sections="mates"`): если у нового - **После смены исполнения в собранном узле проверь сопряжения** (`sections="mates"`): если у нового
@@ -11,11 +11,15 @@
- **`local`** — вставка, переиспользуемая только внутри этого документа. - **`local`** — вставка, переиспользуемая только внутри этого документа.
- **`explode`** — россыпь обычных примитивов: правится по одному, но связи с файлом уже нет. - **`explode`** — россыпь обычных примитивов: правится по одному, но связи с файлом уже нет.
**Имя вставки общее у вставок одного файла одного вида.** Вторая копия того же файла получает имя
первой, и `name` второго вызова не применяется. Ответ `fragment_place` называет фактическое имя
и прямо говорит, если запрошенное не легло. Нужны разные имена — кладите разные файлы.
`angle` (градусы), `scale` и `mirror` задают размещение; зеркалить можно только вставку — у россыпи `angle` (градусы), `scale` и `mirror` задают размещение; зеркалить можно только вставку — у россыпи
отражать нечего. **Зеркало отражает относительно вертикали через точку вставки**, поэтому контур отражать нечего. **Зеркало отражает относительно вертикали через точку вставки**, поэтому контур
уходит в другую сторону от неё: вставка в x=220 после `mirror` занимает 160…220, а не 220…280. уходит в другую сторону от неё: вставка в x=220 после `mirror` занимает 160…220, а не 220…280.
Проверять результат — `list_drawing_objects`: он показывает состав по типам, габарит и все вставки Проверять результат — `describe_drawing`: он показывает состав по типам, габарит и все вставки
с их файлами. Вставка, чей файл потерялся, рисуется пустым местом — в списке она помечена с их файлами. Вставка, чей файл потерялся, рисуется пустым местом — в списке она помечена
недействительной, и это единственный способ отличить её от удавшейся, не глядя на экран. недействительной, и это единственный способ отличить её от удавшейся, не глядя на экран.
@@ -38,9 +38,11 @@
| «сдвинуть грань на N мм» | `move_face` | это он и есть | | «сдвинуть грань на N мм» | `move_face` | это он и есть |
| «диаметр отверстия (бобышки) должен стать D» | **`resize_face`** | задаётся ДИАМЕТР, ось не двигается; `move_face` сдвинул бы стенку на (D−d)/2, и это пришлось бы считать самому | | «диаметр отверстия (бобышки) должен стать D» | **`resize_face`** | задаётся ДИАМЕТР, ось не двигается; `move_face` сдвинул бы стенку на (D−d)/2, и это пришлось бы считать самому |
| «грань должна встать НА объект: на плоскость, на грань соседнего тела» | **`replace_face`** | расстояние считает КОМПАС; `move_face` требует вычислить его заранее | | «грань должна встать НА объект: на плоскость, на грань соседнего тела» | **`replace_face`** | расстояние считает КОМПАС; `move_face` требует вычислить его заранее |
| вставка N мм в призматическую ножку | `split_solid_by_plane` → `move_body` → `move_face` (мост) → `boolean_union` | цепочка проверена end-to-end: проставка 39.45 → 41.45 мм | | «убрать отверстие / скругление / фаску» с импорта (дефичеринг) | **`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` требуют КОМПАС v25; на версиях старше они отвечают отказом с `resize_face`, `replace_face` и `remove_face` требуют КОМПАС v25; на версиях старше они отвечают отказом с
номером установленной версии, и тогда остаётся `move_face` с арифметикой. номером установленной версии, и тогда остаётся `move_face` с арифметикой.
**Проверяйте прямое редактирование РАЗНОСТЬЮ ОБЪЁМОВ против аналитической формулы** — объём и так **Проверяйте прямое редактирование РАЗНОСТЬЮ ОБЪЁМОВ против аналитической формулы** — объём и так
@@ -15,10 +15,39 @@
становится ведомым, внутреннее имя параметра («Расстояние 1») знать не нужно. Переменная должна становится ведомым, внутреннее имя параметра («Расстояние 1») знать не нужно. Переменная должна
существовать ДО операции — потому паспорт и заводят первым. Задним числом и для параметров, существовать ДО операции — потому паспорт и заводят первым. Задним числом и для параметров,
которых нет среди аргументов инструмента (углы уклона, второе направление), — `link_parameter`. которых нет среди аргументов инструмента (углы уклона, второе направление), — `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`; регистр значим), функции в формулах — предупреждение выражениях операций, и в `set_variable`), функции в формулах — предупреждение
(тригонометрия в радианах, разделитель аргументов «;», непонятая запись = молчаливый 0). (тригонометрия в радианах, разделитель аргументов «;», непонятая запись = молчаливый 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` обязателен** и пишется по-русски, со смыслом и единицей; `(ТЗ)` в тексте по-прежнему - **`note` обязателен** и пишется по-русски, со смыслом и единицей; `(ТЗ)` в тексте по-прежнему
полезен человеку, но для машины число из ТЗ метится ПРИЗНАКОМ: полезен человеку, но для машины число из ТЗ метится ПРИЗНАКОМ:
`set_variable([{name:"dish_r", expression:"90", note:"по ТЗ", information:true}])`. Комментарий `set_variable([{name:"dish_r", expression:"90", note:"по ТЗ", information:true}])`. Комментарий
@@ -17,7 +17,7 @@ Zilla Slab): это порядок величины и форма зависим
| **Пришла в CAD-формате**: файл от смежника | `import_drawing` (.dxf/.dwg) → фрагмент → `fragment_place` | | **Пришла в CAD-формате**: файл от смежника | `import_drawing` (.dxf/.dwg) → фрагмент → `fragment_place` |
**Обводка занимает сотни примитивов, и переписывать их в тело вызова незачем.** У `sketch_create`, **Обводка занимает сотни примитивов, и переписывать их в тело вызова незачем.** У `sketch_create`,
`sketch_add` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`; `sketch_update(mode=append)` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`;
сервер читает файл сам. Замер на эмблеме Volvo: SVG в 1.5 КБ даёт 96 примитивов (50 отрезков + сервер читает файл сам. Замер на эмблеме Volvo: SVG в 1.5 КБ даёт 96 примитивов (50 отрезков +
46 дуг) и 9.5 КБ JSON; через `entitiesFile` это один вызов на одну строку аргументов, а эскиз 46 дуг) и 9.5 КБ JSON; через `entitiesFile` это один вызов на одну строку аргументов, а эскиз
строится за один заход. Оба параметра можно задать вместе — сначала `entities`, следом файл: строится за один заход. Оба параметра можно задать вместе — сначала `entities`, следом файл:
+34 -20
View File
@@ -2,7 +2,7 @@
name: kompas-fdm-design name: kompas-fdm-design
description: > description: >
Методика проектирования деталей под FDM/FFF 3D-печать в КОМПАС-3D через MCP-сервер плагина: Методика проектирования деталей под FDM/FFF 3D-печать в КОМПАС-3D через MCP-сервер плагина:
правила DFM (нависания и угол θ_max, толщины стенок n·w, отверстия и teardrop, правила DFM (нависания и угол θ_max, толщины стенок n·w, горизонтальные отверстия,
посадки/зазоры, ориентация под прочность, elephant foot, бобышки/инсёрты/защёлки) ПЛЮС посадки/зазоры, ориентация под прочность, elephant foot, бобышки/инсёрты/защёлки) ПЛЮС
лёгкая самопроверка геометрии инструментами осмотра. Используй, когда задача — спроектировать лёгкая самопроверка геометрии инструментами осмотра. Используй, когда задача — спроектировать
или ДОВЕСТИ деталь, чтобы она хорошо ПЕЧАТАЛАСЬ на FDM. Триггеры: «сделай деталь или ДОВЕСТИ деталь, чтобы она хорошо ПЕЧАТАЛАСЬ на FDM. Триггеры: «сделай деталь
@@ -42,7 +42,9 @@ description: >
- **`θ_max` = предельный угол самонесущей поверхности ОТ ВЕРТИКАЛИ.** `θ_max ≈ arctan(w/2h)` - **`θ_max` = предельный угол самонесущей поверхности ОТ ВЕРТИКАЛИ.** `θ_max ≈ arctan(w/2h)`
(≈45° при `w`=0.4, `h`=0.2). **Дефолт 45°** (PLA, хороший обдув); **40°** для PETG/ABS (≈45° при `w`=0.4, `h`=0.2). **Дефолт 45°** (PLA, хороший обдув); **40°** для PETG/ABS
(эмпирическая поправка на провис, не вывод формулы) или для толстого слоя (`h≥0.3` → формула (эмпирическая поправка на провис, не вывод формулы) или для толстого слоя (`h≥0.3` → формула
даёт ~34°). Нависания, teardrop, фаски, зенковки берут угол из `θ_max`. даёт ~34°). Нависания, фаски, зенковки берут угол из `θ_max`. **Угол, заданный постановкой,
главнее дефолта материала:** ТЗ назвало 45° для PETG — работай с 45° и назови расхождение с
дефолтом 40° в допущениях, а не выбирай молча.
- **Материал** (PLA / PETG / ABS) — модификатор зазоров/мостов/коробления/`θ_max`. См. - **Материал** (PLA / PETG / ABS) — модификатор зазоров/мостов/коробления/`θ_max`. См.
`references/fdm-rules.md`. `references/fdm-rules.md`.
@@ -59,7 +61,7 @@ description: >
«спросить некого» — не повод пропустить решение об ориентации: без него все дальнейшие правила «спросить некого» — не повод пропустить решение об ориентации: без него все дальнейшие правила
повисают. повисают.
- Реши постановку на стол (ось Z = рост слоёв). От неё зависит: где нависания; куда смотрят - Реши постановку на стол (ось Z = рост слоёв). От неё зависит: где нависания; куда смотрят
отверстия (вертикальные → компенсация Ø; горизонтальные → teardrop); путь нагрузки (**держи в отверстия (вертикальные → компенсация Ø; горизонтальные → по возможности развернуть вертикально); путь нагрузки (**держи в
XY**; Z-сжатие можно, Z-растяжение/срез — нет); плоскости сопряжения (на XY-гранях); «лесенка» на XY**; Z-сжатие можно, Z-растяжение/срез — нет); плоскости сопряжения (на XY-гранях); «лесенка» на
наклонных функциональных поверхностях; если поддержки неизбежны — чтобы опорные грани были наклонных функциональных поверхностях; если поддержки неизбежны — чтобы опорные грани были
некритичными/скрытыми. некритичными/скрытыми.
@@ -86,6 +88,12 @@ description: >
4. Порог — межслойная прочность: доля от XY-прочности по §6 `fdm-rules.md`, для **PLA ~20–30 МПа** 4. Порог — межслойная прочность: доля от XY-прочности по §6 `fdm-rules.md`, для **PLA ~20–30 МПа**
(PETG ~15–25, ABS ~8–15). (PETG ~15–25, ABS ~8–15).
**Сечение на пути нагрузки не одно.** Момент проходит через КАЖДОЕ сечение от точки приложения до
опоры: корень стойки, место, где она выходит из основания, тонкие ноги основания, перемычку у
крепежа. Считай прикидку для всех и бери худшее — замер на кронштейне: корень стойки дал запас 32×,
а ноги основания толщиной 4 мм под тот же момент — 3.6×. Самое тонкое место по пути, а не самое
очевидное, и решает ориентацию.
**Точность прикидки — ПОРЯДОК, и в узкой полосе этого мало.** `W = b·h²/6` — это сплошное сечение, **Точность прикидки — ПОРЯДОК, и в узкой полосе этого мало.** `W = b·h²/6` — это сплошное сечение,
а печатная деталь сплошной не бывает: тот же навык требует стенки `n·w` и оставляет заполнение а печатная деталь сплошной не бывает: тот же навык требует стенки `n·w` и оставляет заполнение
по умолчанию, так что настоящий момент сопротивления корневого сечения заметно ниже габаритного по умолчанию, так что настоящий момент сопротивления корневого сечения заметно ниже габаритного
@@ -93,6 +101,9 @@ description: >
не мешает; в полосе **<3×**, где число и решает, погрешность метода равна ширине полосы. Поэтому: не мешает; в полосе **<3×**, где число и решает, погрешность метода равна ширине полосы. Поэтому:
при запасе <3× пересчитайте `W` по фактическому сечению (оболочка `n·w` + заполнение) либо просто при запасе <3× пересчитайте `W` по фактическому сечению (оболочка `n·w` + заполнение) либо просто
возьмите `W` вдвое меньше габаритного и посмотрите, в какой строке таблицы окажетесь. возьмите `W` вдвое меньше габаритного и посмотрите, в какой строке таблицы окажетесь.
`W` и `I` СПЛОШНОГО фактического сечения (с отверстиями, скруглениями, карманами) не считайте по
эскизу — их отдаёт `measure_section(plane, offset)` прямо с построенной детали
(`help(topic="section-properties")`); поправка на оболочку и заполнение остаётся вашей.
| Запас `σ_меж/σ` | Что делать | | Запас `σ_меж/σ` | Что делать |
|---|---| |---|---|
@@ -100,9 +111,10 @@ description: >
| **3–10×** | Держать XY, если это не стоит поддержек на функциональных гранях; несущее сечение поднять (§6: ×2 при неизбежной Z-нагрузке) | | **3–10×** | Держать XY, если это не стоит поддержек на функциональных гранях; несущее сечение поднять (§6: ×2 при неизбежной Z-нагрузке) |
| **≥ 10×** | Требование СНИМАЕТСЯ — «слои на отрыв» здесь не размерный случай. Ориентацию выбирай по печати: сначала нависания, затем опорная площадка и устойчивость | | **≥ 10×** | Требование СНИМАЕТСЯ — «слои на отрыв» здесь не размерный случай. Ориентацию выбирай по печати: сначала нависания, затем опорная площадка и устойчивость |
**Замер (кронштейн камеры):** 150 г на плече 53 мм → `M = 0.150·9.81·53 ≈ 78 Н·мм`; корневое сечение **Пример расчёта** (числа условные — у своей детали бери свои, из постановки и замеров): 150 г на
34×24 → `W = 34·24²/6 ≈ 3.3·10³ мм³`; `σ ≈ 24 кПа` против ~30 МПа межслойной PLA — запас **три плече 50 мм → `M = 0.150·9.81·50 ≈ 74 Н·мм`; сечение 30×20 → `W = 30·20²/6 = 2·10³ мм³`;
порядка**. Слои здесь не решают ничего, и постановка выбрана по нависаниям, а не по прочности. `σ ≈ 37 кПа` против ~30 МПа межслойной PLA — запас **три порядка**. Слои тогда не решают ничего, и
постановку выбирают по нависаниям, а не по прочности.
Без этой прикидки правило «нагрузка в XY» читается как запрет и уводит в худшую по печати ориентацию. Без этой прикидки правило «нагрузка в XY» читается как запрет и уводит в худшую по печати ориентацию.
**Постановки перебирают по граням габарита**, их немного: у плоско-изогнутой детали — две «плашмя» **Постановки перебирают по граням габарита**, их немного: у плоско-изогнутой детали — две «плашмя»
@@ -117,14 +129,13 @@ description: >
2. **Ориентация** (правило 1 + §«когда три требования не сходятся»): нагрузка/косметика — опросом 2. **Ориентация** (правило 1 + §«когда три требования не сходятся»): нагрузка/косметика — опросом
или допущением → перебор постановок с числами → ось слоёв, сопряжения, «лесенка», поддержки. или допущением → перебор постановок с числами → ось слоёв, сопряжения, «лесенка», поддержки.
3. **Правила эскиза/операции** (строй через `kompas-3d`): стенки `n·w`; нависания → скос под 3. **Правила эскиза/операции** (строй через `kompas-3d`): стенки `n·w`; нависания → скос под
`θ_max`; горизонтальные отверстия → teardrop (полная капля; усечённая касательная, если клюв `θ_max`; горизонтальные отверстия → развернуть ось вертикально, мелкое оставить круглым
мешает виду; мягкий колпачок, если по отверстию идёт посадка — выбор и формулы в (короткий мост), крупное — D-отверстие с плоским верхом (`references/fdm-rules.md` §3);
`references/fdm-rules.md` §3), причём у МЕЛКОГО отверстия форму выбирают по ПРОЛЁТУ крыши, вертикальные → компенсация Ø; фаска у основания;
а не по углу боковин; вертикальные → компенсация Ø; фаска у основания;
зазоры посадок (со знаком); заходные фаски; мин. элементы/текст; бобышки/инсёрты/защёлки. зазоры посадок (со знаком); заходные фаски; мин. элементы/текст; бобышки/инсёрты/защёлки.
Числа — в `references/fdm-rules.md`. Числа — в `references/fdm-rules.md`.
4. **Гео-аудит** (`references/geometry-audit.md`) — инструментами осмотра. 4. **Гео-аудит** (`references/geometry-audit.md`) — инструментами осмотра.
5. **Предусловия выдачи**: единое тело/манифолд (`boolean_union` при необходимости) → 5. **Предусловия выдачи**: единое тело/манифолд (`boolean` при необходимости) →
построение чистое. построение чистое.
6. **Чек-лист** → выдача. Обменный файл кладите **только если о нём попросили**: модель самоценна, 6. **Чек-лист** → выдача. Обменный файл кладите **только если о нём попросили**: модель самоценна,
а нарезает её человек сам. Попросили — `export_model` (`.stl` — двоичная сетка для слайсера, а нарезает её человек сам. Попросили — `export_model` (`.stl` — двоичная сетка для слайсера,
@@ -143,10 +154,9 @@ description: >
попадает опорное пятно, без `minArea` — микрогрань, которая нависанием быть не может); попадает опорное пятно, без `minArea` — микрогрань, которая нависанием быть не может);
пролёт каждого моста **замерен** `measure`, а не прикинут, и пролёт каждого моста **замерен** `measure`, а не прикинут, и
укладывается в `references/fdm-rules.md` §2 по короткой стороне; внутренним поддержкам — доступ. укладывается в `references/fdm-rules.md` §2 по короткой стороне; внутренним поддержкам — доступ.
- [ ] Горизонтальные отверстия — teardrop/D (геометрия из `θ_max`), усечённая касательная там, где - [ ] Горизонтальные отверстия — ось развёрнута вертикально, либо мелкое оставлено круглым, либо
клюв мешает виду, либо мягкий колпачок там, где отверстие несёт посадку, и тогда компромисс D-отверстие; пролёт потолка посчитан и укладывается в норму моста; посадочные — под
назван вслух; у формы положе `θ_max` пролёт крыши посчитан и укладывается в норму моста; рассверловку; вертикальные — компенсация Ø; глухие — дно ≥2–3 мм.
вертикальные — компенсация Ø; глухие — дно ≥2–3 мм.
- [ ] Фаска у основания (elephant foot); внутренние углы ≥R0.5; опорная площадка есть, и для - [ ] Фаска у основания (elephant foot); внутренние углы ≥R0.5; опорная площадка есть, и для
высокой детали проверена устойчивость по §«Гео-аудит»: очертание пятна — высокой детали проверена устойчивость по §«Гео-аудит»: очертание пятна —
`list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)`, проекция ЦМ `list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)`, проекция ЦМ
@@ -166,6 +176,10 @@ description: >
Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP — вызовами, Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP — вызовами,
а не пожеланиями: а не пожеланиями:
- **Цилиндры, конусы и торы этот отбор не видит:** нормаль кривой грани берётся в её центре, и у
горизонтального цилиндра она горизонтальна. Их проверяй отдельно: `list_faces(type=cylinder|cone)`
→ ось (`axis`) горизонтальна — у цилиндра нижняя половина потолка нависает (отверстие — §3
`references/fdm-rules.md`), у конуса угол нижней образующей к столу считай из угла конуса.
- **Нависания одним отбором:** `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, - **Нависания одним отбором:** `list_faces(normal="0,0,-1", normalTolerance=90−θ_max,
minZ=<Zmin+0.1>)` — всё вернувшееся кандидаты в нависания, и тем хуже, чем ближе нормаль minZ=<Zmin+0.1>)` — всё вернувшееся кандидаты в нависания, и тем хуже, чем ближе нормаль
к чистому −Z (горизонтальный потолок). При дефолтном `θ_max`=45° допуск равен 45 — это совпадение к чистому −Z (горизонтальный потолок). При дефолтном `θ_max`=45° допуск равен 45 — это совпадение
@@ -183,7 +197,7 @@ description: >
который печатается заведомо. Ставьте `minArea` порядка 5–10 мм², а всё мелкое, что всё же который печатается заведомо. Ставьте `minArea` порядка 5–10 мм², а всё мелкое, что всё же
хотите проверить, судите пролётом (`measure`), а не углом: иначе аудит гонит на редизайн там, хотите проверить, судите пролётом (`measure`), а не углом: иначе аудит гонит на редизайн там,
где всё в порядке. где всё в порядке.
Дальше `list_faces(index=N)` по подозрительным; цилиндр с горизонтальной осью → нужен teardrop. Дальше `list_faces(index=N)` по подозрительным; цилиндр с горизонтальной осью → проверить пролёт потолка (§3 правил).
- **Пролёт моста меряют, а не считают по эскизу:** `measure(kind1="face", index1=…, kind2="face", - **Пролёт моста меряют, а не считают по эскизу:** `measure(kind1="face", index1=…, kind2="face",
index2=…)` между ВНУТРЕННИМИ гранями опор (замер: 49.0 мм между стойками). Сравнивать с §2 index2=…)` между ВНУТРЕННИМИ гранями опор (замер: 49.0 мм между стойками). Сравнивать с §2
`fdm-rules.md`: 49 мм при потолке PLA 15–25 мм — это редизайн, а не «как-нибудь напечатается». `fdm-rules.md`: 49 мм при потолке PLA 15–25 мм — это редизайн, а не «как-нибудь напечатается».
@@ -203,10 +217,10 @@ description: >
Проверок две: проекция ЦМ `(x, y)` обязана лежать **внутри** этого прямоугольника (у консольной Проверок две: проекция ЦМ `(x, y)` обязана лежать **внутри** этого прямоугольника (у консольной
детали «стоя» она легко уходит за него — деталь падает недопечатанной), и высота ЦМ **над столом** детали «стоя» она легко уходит за него — деталь падает недопечатанной), и высота ЦМ **над столом**
(`z_ЦМ − Zmin`) ≲3× полуширины (эвристика; выше — интегральный фланец §5 или разбиение §13). (`z_ЦМ − Zmin`) ≲3× полуширины (эвристика; выше — интегральный фланец §5 или разбиение §13).
**Замер (кронштейн «стоя»):** габарит `Z −50.50…180.00`, ЦМ `(0.00, 4.93, 56.61)`; **Пример** (условные числа): габарит `Z −50…180`, ЦМ `(0, 5, 57)`;
`list_edges(minZ=−51, maxZ=−50)` вернул четыре ребра — `X −50.50…50.50`, `Y 0.00…8.00`, то есть `list_edges(minZ=−51, maxZ=−49)` вернул четыре ребра — `X −50…50`, `Y 0…8`, то есть
пятно 101 × 8 мм. Проекция ЦМ (0.00, 4.93) внутри прямоугольника — первая проверка пройдена; пятно 100 × 8 мм. Проекция ЦМ (0, 5) внутри прямоугольника — первая проверка пройдена;
высота ЦМ над столом 56.61 − (−50.50) = **107.1 мм** при полуширине узкого направления **4 мм**, высота ЦМ над столом 57 − (−50) = **107 мм** при полуширине узкого направления **4 мм**,
это **27×** при пороге 3× — вторая провалена. Сработало именно второе число, и без очертания это **27×** при пороге 3× — вторая провалена. Сработало именно второе число, и без очертания
пятна взять его было неоткуда. пятна взять его было неоткуда.
- **Тело, габарит, номиналы:** `describe_model(sections="bodies")` + чистое построение (единое - **Тело, габарит, номиналы:** `describe_model(sections="bodies")` + чистое построение (единое
@@ -36,48 +36,17 @@
- **Вертикальные (ось ∥ Z)** печатаются уже номинала → **увеличить диаметр модели** (радиус на - **Вертикальные (ось ∥ Z)** печатаются уже номинала → **увеличить диаметр модели** (радиус на
половину): **+0.2 мм (Ø<4)**, **+0.2–0.3 мм (Ø 4–10)**, **+0.1–0.2 мм (Ø>10)**; калибровать, половину): **+0.2 мм (Ø<4)**, **+0.2–0.3 мм (Ø 4–10)**, **+0.1–0.2 мм (Ø>10)**; калибровать,
критичные — рассверливать. критичные — рассверливать.
- **Горизонтальные (ось в XY)** → **teardrop** или **D-отверстие** (плоский верх). Мин. Ø **2 мм**. - **Горизонтальные (ось в XY)** — потолок отверстия печатается нависанием. По порядку предпочтения:
Круглая часть тоже печатается уже → **+0.1–0.2 мм** к её Ø. 1. **Развернуть деталь** так, чтобы ось отверстия стала вертикальной (∥ Z), — если это не спорит
- **Геометрия teardrop (полная капля):** боковины касательны окружности под углом `θ_max` к вертикали с прочностью по слоям (§«Ориентация»).
(с двух сторон), сходятся в вершине на вертикальной оси. Высота вершины над центром = 2. **Мелкое отверстие (Ø ≤ ~6 мм) — оставить круглым.** Потолок — короткий мост в пару
**`r / sin θ_max`**; включённый угол при вершине = **`2·θ_max`**. При `θ_max`=45° → миллиметров, FDM печатает его без поддержек; круглая часть печатается уже → **+0.1–0.2 мм** к Ø.
`r/sin45° = √2·r ≈ 1.414·r` над центром (= **0.414·r над верхом окружности**), угол 90°. 3. **D-отверстие** — плоский верх: хорда на высоте `r·cos φ` над центром превращает потолок в мост
Низ — оставшаяся дуга окружности. Это единственная форма, у которой ВСЯ крыша самонесущая по шириной `2r·sin φ`, материал над хордой остаётся. Контур выреза — ЗАМКНУТЫЙ: дуга окружности
критерию `θ_max`; платой идёт максимальное искажение круга (при `θ_max`=45° некруглыми становятся снизу от одного конца хорды до другого (`arc3points` по точкам хорды и низу) плюс сама хорда
90° дуги из 360°). отрезком. Дополнительный вырез поверх круглого отверстия D-формы не даёт — он только
- **Усечённая касательная капля — когда клюв мешает глазу.** Полная капля при `θ_max`=45° выступает расширяет отверстие. Мост держи **≤ 5–10 мм**.
на 0.414·r, и на мелком отверстии это заметно. Та же конструкция, но с точкой касания на `±φ` от Мин. Ø **2 мм**. Посадочные отверстия (вал, подшипник, штифт) после печати рассверливать.
макушки при `φ < θ_max`: боковины остаются КАСАТЕЛЬНЫМИ (контур гладкий, излома на стыке с дугой
нет, круг не срезается вовсе), а
- вершина над центром = **`r / cos φ`**, то есть выступ над окружностью = **`r·(1/cos φ − 1)`**;
- боковины наклонены к вертикали на **`90° − φ`** — тем положе, чем короче клюв;
- перекрываемый пролёт = **`2r·sin φ`**.
**Судить эту форму по углу боковин бесполезно — судите по пролёту.** У маленького отверстия
`2r·sin φ` укладывается в единицы миллиметров, а мост такой длины FDM печатает не задумываясь:
`θ_max` — критерий для ПРОТЯЖЁННЫХ нависаний, а не для перемычки в пару миллиметров.
Замер (Ø6, `φ`=22.5°): выступ **0.247 мм** против 1.243 у полной капли, пролёт **2.30 мм**,
боковины 67.5° от вертикали — печатается без поддержек, крыша отверстия чистая.
- **Мягкий колпачок — когда круглость важнее, чем полная самонесущесть.** Посадка вала, подшипник,
штифт: полная капля съедает верхнюю четверть окружности, и сопряжение по ней уже не работает.
Тогда заменяют не сектор `±(90−θ_max)`, а УЗКИЙ сектор `±φ` у самой макушки, подняв вершину на
`k` слоёв (`k·h`) над окружностью:
- точки стыка — на `±φ` от макушки, вершина — на оси, на `r + k·h` над центром;
- включённый угол при вершине = **`2·arctan( r·sin φ / (r + k·h − r·cos φ) )`**;
- **угол остаётся ТУПЫМ, пока `r·(sin φ + cos φ − 1) > k·h`** — это и есть связь между шириной
сектора и подъёмом: ужимая `φ`, синхронно снижайте `k`, иначе колпачок вырождается в шпиль.
- Замер (Ø8, `φ`=12°, `k`=2 при `h`=0.2, т.е. подъём 0.4 мм): круглыми остаются **336° из 360°**,
стык отходит от оси на **±0.83 мм**, угол при вершине **119°**, боковины — 59.6° от вертикали.
- **Честная граница приёма:** у чистой окружности зона нависания — сектор `±(90−θ_max)` от макушки
(при 45° это ±45°, ширина `2r·sin45°`≈1.41·r). Колпачок `±12°` снимает только самую макушку —
участок от 12° до 45° остаётся нависанием. То есть это НЕ решение по `θ_max`, а замена плоского
потолка на микро-мост шириной ~`2r·sin φ` за `k` слоёв. Берите его осознанно: круглость в обмен
на частичное улучшение печати, а не на полное.
- **Точки касания задавайте с ПОЛНОЙ точностью — округление рвёт контур.** Дуга плюс две касательные
замыкаются у КОМПАС по допуску жёстче обычного округления: те же координаты, срезанные до 6 знаков
(−16.668356 вместо −16.6683532), дали «код 19: контур должен быть замкнут», и вырез развалился.
Коварство в том, что `sketch_update` отчитался габаритом как об успехе — невалидность вылезла
только предупреждением «2 операц. в ошибке». Считайте `r·sin φ`/`r·cos φ` и подставляйте все знаки.
- **Глухое отверстие:** дно = внутренний мост → **толщина дна ≥2–3 мм** или купольное/ - **Глухое отверстие:** дно = внутренний мост → **толщина дна ≥2–3 мм** или купольное/
вентилируемое. Сквозные предпочтительнее. вентилируемое. Сквозные предпочтительнее.
- **Отступ от края** — через остаточную перемычку: стенка между отверстием и краем **≥2–3·w** - **Отступ от края** — через остаточную перемычку: стенка между отверстием и краем **≥2–3·w**
@@ -9,7 +9,7 @@
|---|---|---| |---|---|---|
| Нависания (приближённо) | `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, minZ=<Zmin+0.1>)` — весь улов кандидаты; подробности `list_faces(index=N)` | ✅ плоские; ⚠️ криволинейные грубо | | Нависания (приближённо) | `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, minZ=<Zmin+0.1>)` — весь улов кандидаты; подробности `list_faces(index=N)` | ✅ плоские; ⚠️ криволинейные грубо |
| Ориентация (геом. прокси) | `describe_model(sections="box")`: как ось слоёв соотносится с габаритом | ⚠️ длинная ось ≠ путь нагрузки | | Ориентация (геом. прокси) | `describe_model(sections="box")`: как ось слоёв соотносится с габаритом | ⚠️ длинная ось ≠ путь нагрузки |
| Горизонтальные круглые отверстия | `list_faces(index=N)`: цилиндр с горизонтальной осью → «нужен teardrop» | ✅ | | Горизонтальные круглые отверстия | `list_faces(index=N)`: цилиндр с горизонтальной осью → пролёт потолка по `fdm-rules.md` §3 | ✅ |
| Пролёт моста | `measure(kind1="face", index1=…, kind2="face", index2=…)` между внутренними гранями опор | ✅ | | Пролёт моста | `measure(kind1="face", index1=…, kind2="face", index2=…)` между внутренними гранями опор | ✅ |
| Устойчивость высокой печати | `describe_model(sections="mass")` — центр масс; `list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)` — очертание опорного пятна по концам рёбер (площадь пятна из `list_faces` для этого не годится) | ✅ проекция ЦМ; ⚠️ порог по высоте — эвристика | | Устойчивость высокой печати | `describe_model(sections="mass")` — центр масс; `list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)` — очертание опорного пятна по концам рёбер (площадь пятна из `list_faces` для этого не годится) | ✅ проекция ЦМ; ⚠️ порог по высоте — эвристика |
| Номиналы / зазоры / габариты | `measure` между гранями; `describe_model(sections="box")` | ✅ | | Номиналы / зазоры / габариты | `measure` между гранями; `describe_model(sections="box")` | ✅ |
+4 -4
View File
@@ -1,6 +1,6 @@
{ {
"version": "0.3.0", "version": "0.7.0",
"tag": "v0.3.0", "tag": "v0.7.0",
"sourceSha": "fcedb44f5661313ffd0570e3808a5309f6ae8cb7", "sourceSha": "a6762d2bdacc62d93705b5c59586ec471854775c",
"built": "2026-08-16T10:02:12Z" "built": "2026-10-27T22:15:59Z"
} }