diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 30f5d34..fbfd5b6 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -11,7 +11,7 @@ { "name": "kompas", "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", "keywords": ["cad", "kompas", "3d", "step", "mcp", "fdm"] } diff --git a/README.md b/README.md index 3d1d6d5..7f9ceed 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ STEP/STL, осмотр и измерение модели — плюс два н | | | |---|---| -| **MCP-сервер `kompas`** | 86 инструментов: документы, эскизы, выдавливание/вращение/по сечениям/по траектории, оболочка, рёбра, уклон, скругления и фаски, массивы и зеркало, отверстия, булевы операции, прямое редактирование B-rep, переменные и параметризация, **исполнения** (несколько геометрий одной модели в одном файле), сборки и сопряжения (в том числе по вспомогательным плоскостям и осям), 2D-чертежи (виды, размеры, обозначения, тех. требования), STEP/STL, осмотр (`describe_model`, `list_faces`, `list_edges`, `measure`) | +| **MCP-сервер `kompas`** | 74 инструмента: документы, эскизы, выдавливание/вращение/по сечениям/по траектории, оболочка, рёбра, уклон, скругления и фаски, массивы и зеркало, отверстия, булевы операции, прямое редактирование B-rep, переменные и параметризация, **исполнения** (несколько геометрий одной модели в одном файле), внешний вид (цвет, прозрачность, текстуры), сборки и сопряжения (в том числе по вспомогательным плоскостям и осям), 2D-чертежи (виды, размеры, обозначения, тех. требования), STEP/STL, осмотр (`describe_model`, `list_faces`, `list_edges`, `measure`) | | **Навык `kompas-3d`** | методика построения: порядок работы, выбор подхода, проверенные приёмы и ловушки | | **Навык `kompas-fdm-design`** | проектирование под FDM/FFF-печать: нависания, толщины стенок, зазоры и посадки, ориентация, бобышки и защёлки | | **Команда `/kompas:doctor`** | диагностика установки | diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index 25214b5..33e95a2 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "kompas", "displayName": "КОМПАС-3D", - "version": "0.3.0", + "version": "0.4.0", "description": "Управление КОМПАС-3D из Claude Code: детали, сборки, чертежи, STEP — через MCP-сервер", "author": { "name": "Shahovalov Mikhail", diff --git a/plugin/README.md b/plugin/README.md index 1f66e00..06368bc 100644 --- a/plugin/README.md +++ b/plugin/README.md @@ -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` подменяет поставленный бинарь своим: diff --git a/plugin/bin/Kompas.Mcp.Core.dll b/plugin/bin/Kompas.Mcp.Core.dll index e49ef48..81b36c6 100644 Binary files a/plugin/bin/Kompas.Mcp.Core.dll and b/plugin/bin/Kompas.Mcp.Core.dll differ diff --git a/plugin/bin/Kompas.Mcp.Core.pdb b/plugin/bin/Kompas.Mcp.Core.pdb index 1cbe18b..87b0e94 100644 Binary files a/plugin/bin/Kompas.Mcp.Core.pdb and b/plugin/bin/Kompas.Mcp.Core.pdb differ diff --git a/plugin/bin/kompas-mcp.deps.json b/plugin/bin/kompas-mcp.deps.json index 52f9b9c..4e6953a 100644 --- a/plugin/bin/kompas-mcp.deps.json +++ b/plugin/bin/kompas-mcp.deps.json @@ -7,9 +7,9 @@ "targets": { ".NETCoreApp,Version=v8.0": {}, ".NETCoreApp,Version=v8.0/win-x64": { - "kompas-mcp/0.3.0": { + "kompas-mcp/0.4.0": { "dependencies": { - "Kompas.Mcp.Core": "0.3.0", + "Kompas.Mcp.Core": "0.4.0", "Microsoft.Extensions.Hosting": "8.0.1", "ModelContextProtocol": "2.0.0" }, @@ -483,21 +483,21 @@ } } }, - "Kompas.Mcp.Core/0.3.0": { + "Kompas.Mcp.Core/0.4.0": { "dependencies": { "Microsoft.Extensions.Logging.Abstractions": "10.0.10" }, "runtime": { "Kompas.Mcp.Core.dll": { - "assemblyVersion": "0.3.0", - "fileVersion": "0.3.0.0" + "assemblyVersion": "0.4.0", + "fileVersion": "0.4.0.0" } } } } }, "libraries": { - "kompas-mcp/0.3.0": { + "kompas-mcp/0.4.0": { "type": "project", "serviceable": false, "sha512": "" @@ -761,7 +761,7 @@ "path": "system.text.json/10.0.10", "hashPath": "system.text.json.10.0.10.nupkg.sha512" }, - "Kompas.Mcp.Core/0.3.0": { + "Kompas.Mcp.Core/0.4.0": { "type": "project", "serviceable": false, "sha512": "" diff --git a/plugin/bin/kompas-mcp.dll b/plugin/bin/kompas-mcp.dll index 54159d9..199ad1f 100644 Binary files a/plugin/bin/kompas-mcp.dll and b/plugin/bin/kompas-mcp.dll differ diff --git a/plugin/bin/kompas-mcp.exe b/plugin/bin/kompas-mcp.exe index 54b71cb..7d83aab 100755 Binary files a/plugin/bin/kompas-mcp.exe and b/plugin/bin/kompas-mcp.exe differ diff --git a/plugin/bin/kompas-mcp.pdb b/plugin/bin/kompas-mcp.pdb index 3fea11f..f09e389 100644 Binary files a/plugin/bin/kompas-mcp.pdb and b/plugin/bin/kompas-mcp.pdb differ diff --git a/plugin/commands/doctor.md b/plugin/commands/doctor.md index 27e659f..ecbed74 100644 --- a/plugin/commands/doctor.md +++ b/plugin/commands/doctor.md @@ -35,7 +35,8 @@ description: "Диагностика установки плагина КОМП 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-класс, то есть установлен ли КОМПАС вообще). Запущен — сервер присоединится к нему; не запущен, но зарегистрирован — попробует запустить новый экземпляр сам; diff --git a/plugin/skills/kompas-3d/SKILL.md b/plugin/skills/kompas-3d/SKILL.md index e78ff42..a547060 100644 --- a/plugin/skills/kompas-3d/SKILL.md +++ b/plugin/skills/kompas-3d/SKILL.md @@ -5,9 +5,10 @@ description: > модификация деталей, импорт/экспорт STEP, работа со сборками, осмотр геометрии снимками и запросами. Используй ВСЕГДА, когда задача — что-то СДЕЛАТЬ в КОМПАС через MCP-инструменты (создать/править деталь, импортировать STEP, разобрать - сборку, померить, отрендерить, экспортировать). Здесь — playbook'и и эвристики, + сборку, померить, раскрасить, отрендерить, экспортировать). Здесь — playbook'и и эвристики, проверенные на практике. Триггеры: «построй деталь в КОМПАС», «импортируй STEP», - «что в этой сборке», «нарасти/измени деталь», «экспортируй STEP», «сделай снимок модели». + «что в этой сборке», «нарасти/измени деталь», «раскрась модель / выдели надпись цветом», «экспортируй STEP», + «сделай снимок модели». --- # kompas-3d — методика управления КОМПАС-3D через MCP @@ -74,7 +75,7 @@ variables | errors | components` (`sections` сужает и ответ, и об и счётчик граней законно остаётся прежним. **Но обратное неверно: «Тел: 1» распад не опровергает.** Счётчик в сводке ОПАЗДЫВАЕТ. Замер (журнал операций кейса с хвостом по сечениям): `loft` построил второе тело и отчитался - «Тел: 1», следом `mirror` — снова «Тел: 1», и только третья операция, `chamfer_edge`, напечатала + «Тел: 1», следом `pattern(kind=mirror)` — снова «Тел: 1», и только третья операция, `chamfer_edge`, напечатала «Тел: 2», хотя между ними ничего не создавалось. Три операции подряд шли по детали, объём которой считал пересечение дважды. Поэтому «Тел: 2» — тревога, которой верят сразу, а «Тел: 1» — не доказательство: там, где важно именно СРАСТАНИЕ (loft/sweep на грань, надпись, примитив @@ -95,7 +96,7 @@ variables | errors | components` (`sections` сужает и ответ, и об `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`. @@ -116,8 +117,8 @@ variables | errors | components` (`sections` сужает и ответ, и об ## Инструменты: где искать каталог -Полный перечень 86 инструментов с параметрами — README плагина §«Инструменты» (единый источник -правды, держать вторую копию здесь не нужно) или `tools/list` самого MCP-сервера. Что известно про +Полный перечень инструментов с параметрами — `tools/list` самого MCP-сервера (единый источник +правды, держать вторую копию здесь не нужно). Что известно про КОНКРЕТНЫЙ инструмент — `help(tool="extrude")`. Три сквозных свойства контракта, которые полезно держать в голове, а не искать заново на каждом инструменте: **размерный параметр принимает число ИЛИ выражение** (имя переменной/формулу — параметр сразу становится ведомым); **объект выбирается индексом** (надёжно) @@ -179,7 +180,7 @@ variables | errors | components` (`sections` сужает и ответ, и об причины, значит фаска выродилась в достройку: убери её `feature_delete`, пологому стыку она и не нужна. - **`result=new` даёт ОТДЕЛЬНОЕ тело**, `subtract` мимо цели сервер ловит сам — и то и другое - видно по сводке «Тел/объём» в ответе; при распаде зови `boolean_union`. + видно по сводке «Тел/объём» в ответе; при распаде зови `boolean`. - **Сужающуюся или изогнутую форму не набирай лесенкой из примитивов.** `primitive` не умеет поворота, и «хвост» из десятка блоков со ступеньками — это обход отсутствующего инструмента, а не решение: он и печатается хуже, и правится только целиком. Бери `loft` по 4–6 сечениям на @@ -197,7 +198,7 @@ variables | errors | components` (`sections` сужает и ответ, и об Опорный сценарий построения, проверен 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. **Запиши замысел переменными** до первого эскиза (см. «Параметризация») и связывай каждый @@ -206,7 +207,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`) — безликая «Деталь» уедет в штамп @@ -230,6 +231,27 @@ variables | errors | components` (`sections` сужает и ответ, и об прямо говорит «⚠ НИЧЕГО НЕ ВЕДЁТ» в этом случае — не успех, хоть число и поменялось. - **Сверка и уборка в конце:** `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). @@ -277,6 +299,51 @@ variables | errors | components` (`sections` сужает и ответ, и об Фрагмент (*.frw, самостоятельный файл переиспользуемого контура/чертежа) — [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 несёт цвета и прозрачность — ответ `export_model` их перечисляет; STL + цветов не несёт. +- **Отделка по материалу**: металл — `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°). Смена рисунка плитку и раскладку сохраняет. В STEP уходят + только цвета — текстуры и вырезы остаются в `.m3d`. +- **Проверка — глазами**: `model_snapshot(view="iso")` после раскраски; что окрашено на самом + деле — `describe_model(sections=appearance)`. Прозрачность снимок не рисует — её видно только + в разделе `appearance`. + +Механизм, имена цветов и измеренные факты — `help(topic="appearance")`. + ## Сборка: собрать своё Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.** @@ -315,7 +382,11 @@ STEP/импортом) — следующий раздел. `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, а @@ -341,7 +412,7 @@ STEP/импортом) — следующий раздел. Хендл — это НЕ индекс: `faceIndex`/`edgeIndices` из `list_faces`/`list_edges` и параметр `feature` у `link_parameter`/`list_parameters` (имя или индекс узла дерева) остаются числовыми. `primitive` и `hole` тоже возвращают хендл (у `hole` — по одному на КАЖДОЕ отверстие серии), - так что примитив и отверстие можно удалить `feature_delete` и размножить `pattern`/`mirror`. + так что примитив и отверстие можно удалить `feature_delete` и размножить `pattern` (и `kind=mirror`). Если ответ вместо хендла говорит «выдать не удалось» — операция построена, но адресовать её нечем: переставить её потом можно только пересборкой. - **Единицы — мм** (геометрия) и **кг** (масса). Локальные координаты эскиза ≠ мировые координаты @@ -362,7 +433,7 @@ STEP/импортом) — следующий раздел. сохранения. - **Строишь параллельно с кем-то — `instance="private"`** при первом `kompas_connect` (потом режим - не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_set_visible true` + не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_connect(visible=true)` покажет). - **`shared` оставляй**, когда работа идёт на глазах у человека и ты единственный агент. - **Один файл в двух экземплярах не открыть** — второй получит его только на чтение: работу делите @@ -370,11 +441,12 @@ STEP/импортом) — следующий раздел. ## Открытые вопросы / границы -- **Параметрика работает через параметры ОПЕРАЦИЙ, а не координаты ВНУТРИ эскиза** — сдвинуть - контур переменной нельзя, только пересобрать эскиз (`sketch_update`). Но это ограничение уже - границей: **плоскость** эскиза — обычный узел дерева с параметром «Расстояние», и она - параметризуется как всё остальное. Планируй членение так, чтобы изменяемое задавалось параметром - операции (глубина, радиус, габарит примитива) или положением плоскости, а не координатами точек. +- **Координата в точке — число или выражение (считается один раз), а форму контура ведут `dimensions`** с выражениями + (`help(topic="sketch-dimensions")`). Уже наложенный размер перепривязывается без пересборки: + `link_parameter(feature=<узел эскиза>, parameter="v15")` — имя `vNN` есть в ответе + `sketch_create` и в `list_parameters` (у одноимённых «Линейный размер» — в скобках). Эскиз без + размеров переменной не двигается — только пересборкой (`sketch_update`); положение эскиза задаёт + **плоскость** — обычный узел с параметром «Расстояние». - **2D покрыт вместе с разрезом и сечением.** Есть виды (с выбором набора, ориентации главного и невидимых линий), разрез/сечение, листы, штамп, размеры с допусками, осевые, обозначения, техтребования, удаление и сдвиг объекта, вывод в растр — методика в §«Чертёж». Нет выносного diff --git a/plugin/skills/kompas-3d/reference/drawing-playbook.md b/plugin/skills/kompas-3d/reference/drawing-playbook.md index 8c8d20f..a9340be 100644 --- a/plugin/skills/kompas-3d/reference/drawing-playbook.md +++ b/plugin/skills/kompas-3d/reference/drawing-playbook.md @@ -13,12 +13,12 @@ ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость с наибольшей информацией. 2. **`drawing_set_sheet_format`** (формат до видов — иначе виды придётся двигать), при - необходимости `drawing_add_sheet` для второго листа. + необходимости `drawing_set_sheet_format(add=true)` для второго листа. 3. **`drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…)`** — бери ровно те проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. **Главный вид входит в набор сам**: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому `views=["top"]` даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими. -4. **Координаты — замером, а не формулой.** `drawing_get_view_info(viewNumber)` отдаёт паспорт вида +4. **Координаты — замером, а не формулой.** `describe_drawing(sections=view, viewNumber)` отдаёт паспорт вида одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид @@ -34,7 +34,7 @@ 6. **Размеры**, `drawing_add_axis` (осевые и центровые), шероховатость, выноски, техтребования, штамп. **Осевые сначала посмотри, потом добивай**: ассоциативные виды приходят со СВОИМИ центровыми и осевыми, которые КОМПАС ставит сам, и `drawing_add_axis` вслепую даёт дубли поверх - существующих. Сначала `list_drawing_objects(kind="axis"|"centreMarker", viewNumber=…)`. + существующих. Сначала `describe_drawing(kind="axis"|"centreMarker", viewNumber=…)`. 7. **`drawing_export_image`** — посмотреть глазами. Пока картинки не было, чертёж не сдан. ## Разрез @@ -48,16 +48,16 @@ стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к штриховой линии не привязывают. - **Веди линию с запасом за габарит** (плита 60 мм → от −40 до +40): линия по самому краю режет не - всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `drawing_get_view_info`. + всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `describe_drawing(sections=view)`. - **Строй разрез, когда модель готова**: после правки детали перестраивается только ПЕРВЫЙ разрез базового вида. Модель всё же изменилась — снеси разрезы и построй заново. - Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру. **Промах простановки лечится, а не остаётся навсегда.** Отката (undo) у чертежа нет, но -`list_drawing_objects` показывает обозначения с индексами, `drawing_delete_object` убирает одно, а +`describe_drawing` показывает обозначения с индексами, `drawing_delete(target=object)` убирает одно, а `drawing_move_object` его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не заменой размера на выноску. Так же правится и компоновка: `drawing_move_view` переставляет вид со -всеми обозначениями, `drawing_add_view` доносит недостающую проекцию, `drawing_delete_view` убирает +всеми обозначениями, `drawing_create_standard_views(views=[])` доносит недостающую проекцию, `drawing_delete(target=view)` убирает лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления — `help(topic="drawing-fixing")`. diff --git a/plugin/skills/kompas-3d/reference/embodiments-playbook.md b/plugin/skills/kompas-3d/reference/embodiments-playbook.md index 8c8e5ad..838d1a9 100644 --- a/plugin/skills/kompas-3d/reference/embodiments-playbook.md +++ b/plugin/skills/kompas-3d/reference/embodiments-playbook.md @@ -27,6 +27,12 @@ `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"`): если у нового diff --git a/plugin/skills/kompas-3d/reference/fragments.md b/plugin/skills/kompas-3d/reference/fragments.md index c1627c2..565ab15 100644 --- a/plugin/skills/kompas-3d/reference/fragments.md +++ b/plugin/skills/kompas-3d/reference/fragments.md @@ -11,11 +11,15 @@ - **`local`** — вставка, переиспользуемая только внутри этого документа. - **`explode`** — россыпь обычных примитивов: правится по одному, но связи с файлом уже нет. +**Имя вставки общее у вставок одного файла одного вида.** Вторая копия того же файла получает имя +первой, и `name` второго вызова не применяется. Ответ `fragment_place` называет фактическое имя +и прямо говорит, если запрошенное не легло. Нужны разные имена — кладите разные файлы. + `angle` (градусы), `scale` и `mirror` задают размещение; зеркалить можно только вставку — у россыпи отражать нечего. **Зеркало отражает относительно вертикали через точку вставки**, поэтому контур уходит в другую сторону от неё: вставка в x=220 после `mirror` занимает 160…220, а не 220…280. -Проверять результат — `list_drawing_objects`: он показывает состав по типам, габарит и все вставки +Проверять результат — `describe_drawing`: он показывает состав по типам, габарит и все вставки с их файлами. Вставка, чей файл потерялся, рисуется пустым местом — в списке она помечена недействительной, и это единственный способ отличить её от удавшейся, не глядя на экран. diff --git a/plugin/skills/kompas-3d/reference/import-playbook.md b/plugin/skills/kompas-3d/reference/import-playbook.md index c0f8474..750a74c 100644 --- a/plugin/skills/kompas-3d/reference/import-playbook.md +++ b/plugin/skills/kompas-3d/reference/import-playbook.md @@ -38,7 +38,7 @@ | «сдвинуть грань на N мм» | `move_face` | это он и есть | | «диаметр отверстия (бобышки) должен стать D» | **`resize_face`** | задаётся ДИАМЕТР, ось не двигается; `move_face` сдвинул бы стенку на (D−d)/2, и это пришлось бы считать самому | | «грань должна встать НА объект: на плоскость, на грань соседнего тела» | **`replace_face`** | расстояние считает КОМПАС; `move_face` требует вычислить его заранее | - | вставка N мм в призматическую ножку | `split_solid_by_plane` → `move_body` → `move_face` (мост) → `boolean_union` | цепочка проверена end-to-end: проставка 39.45 → 41.45 мм | + | вставка N мм в призматическую ножку | `split_solid_by_plane` → `move_body` → `move_face` (мост) → `boolean` | цепочка проверена end-to-end: проставка 39.45 → 41.45 мм | `resize_face` и `replace_face` требуют КОМПАС v25; на версиях старше они отвечают отказом с номером установленной версии, и тогда остаётся `move_face` с арифметикой. diff --git a/plugin/skills/kompas-3d/reference/parametrization.md b/plugin/skills/kompas-3d/reference/parametrization.md index 579856e..1c4b4ca 100644 --- a/plugin/skills/kompas-3d/reference/parametrization.md +++ b/plugin/skills/kompas-3d/reference/parametrization.md @@ -15,10 +15,39 @@ становится ведомым, внутреннее имя параметра («Расстояние 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`; регистр значим), функции в формулах — предупреждение + выражениях операций, и в `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}])`. Комментарий diff --git a/plugin/skills/kompas-3d/reference/text-and-relief.md b/plugin/skills/kompas-3d/reference/text-and-relief.md index fccf839..718f3ea 100644 --- a/plugin/skills/kompas-3d/reference/text-and-relief.md +++ b/plugin/skills/kompas-3d/reference/text-and-relief.md @@ -17,7 +17,7 @@ Zilla Slab): это порядок величины и форма зависим | **Пришла в CAD-формате**: файл от смежника | `import_drawing` (.dxf/.dwg) → фрагмент → `fragment_place` | **Обводка занимает сотни примитивов, и переписывать их в тело вызова незачем.** У `sketch_create`, -`sketch_add` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`; +`sketch_update(mode=append)` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`; сервер читает файл сам. Замер на эмблеме Volvo: SVG в 1.5 КБ даёт 96 примитивов (50 отрезков + 46 дуг) и 9.5 КБ JSON; через `entitiesFile` это один вызов на одну строку аргументов, а эскиз строится за один заход. Оба параметра можно задать вместе — сначала `entities`, следом файл: diff --git a/plugin/skills/kompas-fdm-design/SKILL.md b/plugin/skills/kompas-fdm-design/SKILL.md index aadbde6..f5cecde 100644 --- a/plugin/skills/kompas-fdm-design/SKILL.md +++ b/plugin/skills/kompas-fdm-design/SKILL.md @@ -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`. @@ -59,7 +61,7 @@ description: > «спросить некого» — не повод пропустить решение об ориентации: без него все дальнейшие правила повисают. - Реши постановку на стол (ось Z = рост слоёв). От неё зависит: где нависания; куда смотрят - отверстия (вертикальные → компенсация Ø; горизонтальные → teardrop); путь нагрузки (**держи в + отверстия (вертикальные → компенсация Ø; горизонтальные → по возможности развернуть вертикально); путь нагрузки (**держи в XY**; Z-сжатие можно, Z-растяжение/срез — нет); плоскости сопряжения (на XY-гранях); «лесенка» на наклонных функциональных поверхностях; если поддержки неизбежны — чтобы опорные грани были некритичными/скрытыми. @@ -86,6 +88,12 @@ description: > 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` и оставляет заполнение по умолчанию, так что настоящий момент сопротивления корневого сечения заметно ниже габаритного @@ -93,6 +101,9 @@ description: > не мешает; в полосе **<3×**, где число и решает, погрешность метода равна ширине полосы. Поэтому: при запасе <3× пересчитайте `W` по фактическому сечению (оболочка `n·w` + заполнение) либо просто возьмите `W` вдвое меньше габаритного и посмотрите, в какой строке таблицы окажетесь. +`W` и `I` СПЛОШНОГО фактического сечения (с отверстиями, скруглениями, карманами) не считайте по +эскизу — их отдаёт `measure_section(plane, offset)` прямо с построенной детали +(`help(topic="section-properties")`); поправка на оболочку и заполнение остаётся вашей. | Запас `σ_меж/σ` | Что делать | |---|---| @@ -100,9 +111,10 @@ description: > | **3–10×** | Держать XY, если это не стоит поддержек на функциональных гранях; несущее сечение поднять (§6: ×2 при неизбежной Z-нагрузке) | | **≥ 10×** | Требование СНИМАЕТСЯ — «слои на отрыв» здесь не размерный случай. Ориентацию выбирай по печати: сначала нависания, затем опорная площадка и устойчивость | -**Замер (кронштейн камеры):** 150 г на плече 53 мм → `M = 0.150·9.81·53 ≈ 78 Н·мм`; корневое сечение -34×24 → `W = 34·24²/6 ≈ 3.3·10³ мм³`; `σ ≈ 24 кПа` против ~30 МПа межслойной PLA — запас **три -порядка**. Слои здесь не решают ничего, и постановка выбрана по нависаниям, а не по прочности. +**Пример расчёта** (числа условные — у своей детали бери свои, из постановки и замеров): 150 г на +плече 50 мм → `M = 0.150·9.81·50 ≈ 74 Н·мм`; сечение 30×20 → `W = 30·20²/6 = 2·10³ мм³`; +`σ ≈ 37 кПа` против ~30 МПа межслойной PLA — запас **три порядка**. Слои тогда не решают ничего, и +постановку выбирают по нависаниям, а не по прочности. Без этой прикидки правило «нагрузка в XY» читается как запрет и уводит в худшую по печати ориентацию. **Постановки перебирают по граням габарита**, их немного: у плоско-изогнутой детали — две «плашмя» @@ -117,14 +129,13 @@ description: > 2. **Ориентация** (правило 1 + §«когда три требования не сходятся»): нагрузка/косметика — опросом или допущением → перебор постановок с числами → ось слоёв, сопряжения, «лесенка», поддержки. 3. **Правила эскиза/операции** (строй через `kompas-3d`): стенки `n·w`; нависания → скос под - `θ_max`; горизонтальные отверстия → teardrop (полная капля; усечённая касательная, если клюв - мешает виду; мягкий колпачок, если по отверстию идёт посадка — выбор и формулы в - `references/fdm-rules.md` §3), причём у МЕЛКОГО отверстия форму выбирают по ПРОЛЁТУ крыши, - а не по углу боковин; вертикальные → компенсация Ø; фаска у основания; + `θ_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` — двоичная сетка для слайсера, @@ -143,10 +154,9 @@ description: > попадает опорное пятно, без `minArea` — микрогрань, которая нависанием быть не может); пролёт каждого моста **замерен** `measure`, а не прикинут, и укладывается в `references/fdm-rules.md` §2 по короткой стороне; внутренним поддержкам — доступ. -- [ ] Горизонтальные отверстия — teardrop/D (геометрия из `θ_max`), усечённая касательная там, где - клюв мешает виду, либо мягкий колпачок там, где отверстие несёт посадку, и тогда компромисс - назван вслух; у формы положе `θ_max` пролёт крыши посчитан и укладывается в норму моста; - вертикальные — компенсация Ø; глухие — дно ≥2–3 мм. +- [ ] Горизонтальные отверстия — ось развёрнута вертикально, либо мелкое оставлено круглым, либо + D-отверстие; пролёт потолка посчитан и укладывается в норму моста; посадочные — под + рассверловку; вертикальные — компенсация Ø; глухие — дно ≥2–3 мм. - [ ] Фаска у основания (elephant foot); внутренние углы ≥R0.5; опорная площадка есть, и для высокой детали проверена устойчивость по §«Гео-аудит»: очертание пятна — `list_edges(minZ=, maxZ=)`, проекция ЦМ @@ -166,6 +176,10 @@ description: > Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP — вызовами, а не пожеланиями: +- **Цилиндры, конусы и торы этот отбор не видит:** нормаль кривой грани берётся в её центре, и у + горизонтального цилиндра она горизонтальна. Их проверяй отдельно: `list_faces(type=cylinder|cone)` + → ось (`axis`) горизонтальна — у цилиндра нижняя половина потолка нависает (отверстие — §3 + `references/fdm-rules.md`), у конуса угол нижней образующей к столу считай из угла конуса. - **Нависания одним отбором:** `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, minZ=)` — всё вернувшееся кандидаты в нависания, и тем хуже, чем ближе нормаль к чистому −Z (горизонтальный потолок). При дефолтном `θ_max`=45° допуск равен 45 — это совпадение @@ -183,7 +197,7 @@ description: > который печатается заведомо. Ставьте `minArea` порядка 5–10 мм², а всё мелкое, что всё же хотите проверить, судите пролётом (`measure`), а не углом: иначе аудит гонит на редизайн там, где всё в порядке. - Дальше `list_faces(index=N)` по подозрительным; цилиндр с горизонтальной осью → нужен teardrop. + Дальше `list_faces(index=N)` по подозрительным; цилиндр с горизонтальной осью → проверить пролёт потолка (§3 правил). - **Пролёт моста меряют, а не считают по эскизу:** `measure(kind1="face", index1=…, kind2="face", index2=…)` между ВНУТРЕННИМИ гранями опор (замер: 49.0 мм между стойками). Сравнивать с §2 `fdm-rules.md`: 49 мм при потолке PLA 15–25 мм — это редизайн, а не «как-нибудь напечатается». @@ -203,10 +217,10 @@ description: > Проверок две: проекция ЦМ `(x, y)` обязана лежать **внутри** этого прямоугольника (у консольной детали «стоя» она легко уходит за него — деталь падает недопечатанной), и высота ЦМ **над столом** (`z_ЦМ − Zmin`) ≲3× полуширины (эвристика; выше — интегральный фланец §5 или разбиение §13). - **Замер (кронштейн «стоя»):** габарит `Z −50.50…180.00`, ЦМ `(0.00, 4.93, 56.61)`; - `list_edges(minZ=−51, maxZ=−50)` вернул четыре ребра — `X −50.50…50.50`, `Y 0.00…8.00`, то есть - пятно 101 × 8 мм. Проекция ЦМ (0.00, 4.93) внутри прямоугольника — первая проверка пройдена; - высота ЦМ над столом 56.61 − (−50.50) = **107.1 мм** при полуширине узкого направления **4 мм**, + **Пример** (условные числа): габарит `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")` + чистое построение (единое diff --git a/plugin/skills/kompas-fdm-design/references/fdm-rules.md b/plugin/skills/kompas-fdm-design/references/fdm-rules.md index bb3f98a..f9391e9 100644 --- a/plugin/skills/kompas-fdm-design/references/fdm-rules.md +++ b/plugin/skills/kompas-fdm-design/references/fdm-rules.md @@ -36,48 +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°. - Низ — оставшаяся дуга окружности. Это единственная форма, у которой ВСЯ крыша самонесущая по - критерию `θ_max`; платой идёт максимальное искажение круга (при `θ_max`=45° некруглыми становятся - 90° дуги из 360°). -- **Усечённая касательная капля — когда клюв мешает глазу.** Полная капля при `θ_max`=45° выступает - на 0.414·r, и на мелком отверстии это заметно. Та же конструкция, но с точкой касания на `±φ` от - макушки при `φ < θ_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 φ` и подставляйте все знаки. +- **Горизонтальные (ось в 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** diff --git a/plugin/skills/kompas-fdm-design/references/geometry-audit.md b/plugin/skills/kompas-fdm-design/references/geometry-audit.md index 8c27323..17053fc 100644 --- a/plugin/skills/kompas-fdm-design/references/geometry-audit.md +++ b/plugin/skills/kompas-fdm-design/references/geometry-audit.md @@ -9,7 +9,7 @@ |---|---|---| | Нависания (приближённо) | `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, minZ=)` — весь улов кандидаты; подробности `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=, maxZ=)` — очертание опорного пятна по концам рёбер (площадь пятна из `list_faces` для этого не годится) | ✅ проекция ЦМ; ⚠️ порог по высоте — эвристика | | Номиналы / зазоры / габариты | `measure` между гранями; `describe_model(sections="box")` | ✅ | diff --git a/release.json b/release.json index 3273d02..7fbc944 100644 --- a/release.json +++ b/release.json @@ -1,6 +1,6 @@ { - "version": "0.3.0", - "tag": "v0.3.0", - "sourceSha": "fcedb44f5661313ffd0570e3808a5309f6ae8cb7", - "built": "2026-08-16T10:02:12Z" + "version": "0.4.0", + "tag": "v0.4.0", + "sourceSha": "f1ecc6ff5a923d524a7aa8dc7b97c538d9cf1bb3", + "built": "2026-10-15T03:15:33Z" }