Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0720fd7397 | ||
|
|
94e044bd03 | ||
|
|
c62794b415 | ||
|
|
3c091adbb2 |
@@ -11,7 +11,7 @@
|
|||||||
{
|
{
|
||||||
"name": "kompas",
|
"name": "kompas",
|
||||||
"source": "./plugin",
|
"source": "./plugin",
|
||||||
"description": "Управление КОМПАС-3D из Claude Code: 85 MCP-инструментов (детали, эскизы, формообразующие операции, массивы, отверстия, сборки и сопряжения, 2D-чертежи, STEP/STL, осмотр модели) и два навыка — построение (kompas-3d) и проектирование под FDM-печать (kompas-fdm-design).",
|
"description": "Управление КОМПАС-3D из Claude Code: 74 MCP-инструмента (детали, эскизы, формообразующие операции, массивы, отверстия, исполнения, внешний вид, сборки и сопряжения, 2D-чертежи, STEP/STL, осмотр модели) и два навыка — построение (kompas-3d) и проектирование под FDM-печать (kompas-fdm-design).",
|
||||||
"category": "productivity",
|
"category": "productivity",
|
||||||
"keywords": ["cad", "kompas", "3d", "step", "mcp", "fdm"]
|
"keywords": ["cad", "kompas", "3d", "step", "mcp", "fdm"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ STEP/STL, осмотр и измерение модели — плюс два н
|
|||||||
## Что нужно до установки
|
## Что нужно до установки
|
||||||
|
|
||||||
- **Windows x64** — сервер является COM-клиентом КОМПАС и работает только на той же машине;
|
- **Windows x64** — сервер является COM-клиентом КОМПАС и работает только на той же машине;
|
||||||
- **установленный КОМПАС-3D** (проверено на v24 Home) **с компонентом SDK**. Interop-сборки
|
- **установленный КОМПАС-3D** (проверено на v25 Home, v24 Home тоже поддерживается) **с компонентом SDK**. Interop-сборки
|
||||||
принадлежат АСКОН, в поставку не входят и берутся из установки
|
принадлежат АСКОН, в поставку не входят и берутся из установки
|
||||||
(`SDK\Samples\CSharp.zip`, каталог `Common`); при первом запуске они распаковываются
|
(`SDK\Samples\CSharp.zip`, каталог `Common`); при первом запуске они распаковываются
|
||||||
в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`. Если SDK не установлен, укажите каталог
|
в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`. Если SDK не установлен, укажите каталог
|
||||||
@@ -48,7 +48,7 @@ STEP/STL, осмотр и измерение модели — плюс два н
|
|||||||
|
|
||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **MCP-сервер `kompas`** | 85 инструментов: документы, эскизы, выдавливание/вращение/по сечениям/по траектории, оболочка, рёбра, уклон, скругления и фаски, массивы и зеркало, отверстия, булевы операции, прямое редактирование 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-3d`** | методика построения: порядок работы, выбор подхода, проверенные приёмы и ловушки |
|
||||||
| **Навык `kompas-fdm-design`** | проектирование под FDM/FFF-печать: нависания, толщины стенок, зазоры и посадки, ориентация, бобышки и защёлки |
|
| **Навык `kompas-fdm-design`** | проектирование под FDM/FFF-печать: нависания, толщины стенок, зазоры и посадки, ориентация, бобышки и защёлки |
|
||||||
| **Команда `/kompas:doctor`** | диагностика установки |
|
| **Команда `/kompas:doctor`** | диагностика установки |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "kompas",
|
"name": "kompas",
|
||||||
"displayName": "КОМПАС-3D",
|
"displayName": "КОМПАС-3D",
|
||||||
"version": "0.1.0",
|
"version": "0.4.0",
|
||||||
"description": "Управление КОМПАС-3D из Claude Code: детали, сборки, чертежи, STEP — через MCP-сервер",
|
"description": "Управление КОМПАС-3D из Claude Code: детали, сборки, чертежи, STEP — через MCP-сервер",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Shahovalov Mikhail",
|
"name": "Shahovalov Mikhail",
|
||||||
|
|||||||
+8
-1
@@ -6,7 +6,7 @@
|
|||||||
## Предпосылки
|
## Предпосылки
|
||||||
|
|
||||||
- Windows x64;
|
- Windows x64;
|
||||||
- установленный КОМПАС-3D (проверено на v24 Home) — сервер является COM-клиентом, а не автономным
|
- установленный КОМПАС-3D (проверено на v25 Home, v24 Home тоже поддерживается) — сервер является COM-клиентом, а не автономным
|
||||||
CAD-движком, и работает только на той же машине. Запускать заранее не нужно: сервер присоединится
|
CAD-движком, и работает только на той же машине. Запускать заранее не нужно: сервер присоединится
|
||||||
к открытому окну, а если его нет — запустит экземпляр сам;
|
к открытому окну, а если его нет — запустит экземпляр сам;
|
||||||
- КОМПАС установлен **вместе с компонентом SDK**: interop-сборки принадлежат АСКОН, в поставку
|
- КОМПАС установлен **вместе с компонентом SDK**: interop-сборки принадлежат АСКОН, в поставку
|
||||||
@@ -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` подменяет поставленный бинарь своим:
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -7,9 +7,9 @@
|
|||||||
"targets": {
|
"targets": {
|
||||||
".NETCoreApp,Version=v8.0": {},
|
".NETCoreApp,Version=v8.0": {},
|
||||||
".NETCoreApp,Version=v8.0/win-x64": {
|
".NETCoreApp,Version=v8.0/win-x64": {
|
||||||
"kompas-mcp/0.1.0": {
|
"kompas-mcp/0.4.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Kompas.Mcp.Core": "0.1.0",
|
"Kompas.Mcp.Core": "0.4.0",
|
||||||
"Microsoft.Extensions.Hosting": "8.0.1",
|
"Microsoft.Extensions.Hosting": "8.0.1",
|
||||||
"ModelContextProtocol": "2.0.0"
|
"ModelContextProtocol": "2.0.0"
|
||||||
},
|
},
|
||||||
@@ -483,21 +483,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Kompas.Mcp.Core/0.1.0": {
|
"Kompas.Mcp.Core/0.4.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10"
|
"Microsoft.Extensions.Logging.Abstractions": "10.0.10"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"Kompas.Mcp.Core.dll": {
|
"Kompas.Mcp.Core.dll": {
|
||||||
"assemblyVersion": "0.1.0",
|
"assemblyVersion": "0.4.0",
|
||||||
"fileVersion": "0.1.0.0"
|
"fileVersion": "0.4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"libraries": {
|
"libraries": {
|
||||||
"kompas-mcp/0.1.0": {
|
"kompas-mcp/0.4.0": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"serviceable": false,
|
"serviceable": false,
|
||||||
"sha512": ""
|
"sha512": ""
|
||||||
@@ -761,7 +761,7 @@
|
|||||||
"path": "system.text.json/10.0.10",
|
"path": "system.text.json/10.0.10",
|
||||||
"hashPath": "system.text.json.10.0.10.nupkg.sha512"
|
"hashPath": "system.text.json.10.0.10.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Kompas.Mcp.Core/0.1.0": {
|
"Kompas.Mcp.Core/0.4.0": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"serviceable": false,
|
"serviceable": false,
|
||||||
"sha512": ""
|
"sha512": ""
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -35,7 +35,8 @@ description: "Диагностика установки плагина КОМП
|
|||||||
|
|
||||||
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-класс, то есть установлен ли КОМПАС вообще). Запущен — сервер
|
||||||
присоединится к нему; не запущен, но зарегистрирован — попробует запустить новый экземпляр сам;
|
присоединится к нему; не запущен, но зарегистрирован — попробует запустить новый экземпляр сам;
|
||||||
|
|||||||
+225
-322
@@ -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
|
||||||
@@ -23,6 +24,26 @@ MCP-сервер даёт **общие** операции КОМПАС (эски
|
|||||||
Любая задача «сделать что-то В КОМПАС» через MCP: создать/править деталь, эскизы и операции,
|
Любая задача «сделать что-то В КОМПАС» через MCP: создать/править деталь, эскизы и операции,
|
||||||
импорт/экспорт обменных форматов, разбор сборки, измерения, снимки.
|
импорт/экспорт обменных форматов, разбор сборки, измерения, снимки.
|
||||||
|
|
||||||
|
## Указатель: тип задачи → файл
|
||||||
|
|
||||||
|
Этот файл — ядро: применяется в любой задаче. Развёрнутый playbook под конкретный тип работы вынесен
|
||||||
|
в `reference/*.md` — читай Read'ом ровно тот файл, что подошёл, остальные не трогай.
|
||||||
|
|
||||||
|
| Задача | Файл |
|
||||||
|
|---|---|
|
||||||
|
| Переменные, параметрическая модель | `reference/parametrization.md` |
|
||||||
|
| Надпись, логотип, SVG, рельеф, выбор маршрута для внешнего контура | `reference/text-and-relief.md` |
|
||||||
|
| Переиспользуемый чертёжный блок (*.frw) | `reference/fragments.md` |
|
||||||
|
| Сборка с нуля (вставка, сопряжения, фиксация) | `reference/assembly-playbook.md` |
|
||||||
|
| Чертёж по ГОСТ, виды, разрез, размеры | `reference/drawing-playbook.md` |
|
||||||
|
| Разбор ЧУЖОЙ модели/сборки (импорт, STEP) | `reference/import-playbook.md` |
|
||||||
|
| Исполнения (типоразмеры, зеркала в одном файле) | `reference/embodiments-playbook.md` |
|
||||||
|
|
||||||
|
Ни один файл не подошёл — вопрос, скорее всего, про механику КОНКРЕТНОГО инструмента, а не про
|
||||||
|
порядок работы: туда — `help(topic="…")`/`help(query="…")` (см. ниже), а не в `reference/`.
|
||||||
|
Не нашёлся и там — `Grep` по `reference/**` словами задачи: это и есть весь механизм поиска, ничего
|
||||||
|
специального заводить не пришлось.
|
||||||
|
|
||||||
## Два правила прежде всего
|
## Два правила прежде всего
|
||||||
|
|
||||||
**1. «Зрение» — структурное, не по картинке.** «Увидеть» деталь = **`describe_model`** — паспорт
|
**1. «Зрение» — структурное, не по картинке.** «Увидеть» деталь = **`describe_model`** — паспорт
|
||||||
@@ -34,21 +55,48 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
форма, ориентация, правдоподобность, «куда смотрит грань»): снимок дорог по контексту и менее
|
форма, ориентация, правдоподобность, «куда смотрит грань»): снимок дорог по контексту и менее
|
||||||
точен, чем числа.
|
точен, чем числа.
|
||||||
|
|
||||||
**2. Ответ мутирующей операции — это ТРИ проверки, читай все.** Любая операция может «пройти»
|
**1а. Осмотр НЕ перестраивает документ.** Если модель правили снаружи (человек в GUI, соседний
|
||||||
|
агент) или операция запросила перестроение, `describe_model` покажет числа ДО правки — и ответ
|
||||||
|
будет выглядеть безупречным: размеры новые, положения старые, сопряжения валидны. Такой ответ сам
|
||||||
|
скажет «Документ ТРЕБУЕТ ПЕРЕСТРОЕНИЯ» (`needsRebuild: true`); увидел — `rebuild` и повтори осмотр,
|
||||||
|
выводов по непересчитанной модели не делай.
|
||||||
|
|
||||||
|
**2. Ответ мутирующей операции — это НЕСКОЛЬКО проверок, читай все.** Любая операция может «пройти»
|
||||||
(`Create()==true`), оставив деталь в ошибке, поэтому каждая мутирующая операция сама дописывает
|
(`Create()==true`), оставив деталь в ошибке, поэтому каждая мутирующая операция сама дописывает
|
||||||
к ответу итог проверки построения и сводку состояния «Тел: N, объём V мм³»:
|
к ответу итог проверки построения и сводку состояния «Тел: N, объём V мм³»:
|
||||||
|
|
||||||
- **«⚠ N операц. в ошибке»** (напр. `et3dError54`) — деталь невалидна: не продолжай и не
|
- **«⚠ N операц. в ошибке»** (напр. `et3dError54`) — деталь невалидна: не продолжай и не
|
||||||
экспортируй, исправь или переделай другим методом. «Построение чистое» = порядок.
|
экспортируй, исправь или переделай другим методом. «Построение чистое» = порядок.
|
||||||
|
Строки с «ℹ» — не отказы: «требуется перестроение» лечится `rebuild`, а «не определено
|
||||||
|
положение (N)» означает, что компоненту не хватает сопряжений или фиксации. Бросать из-за них
|
||||||
|
исправную сборку не нужно; в обеих названы имя и индекс компонента.
|
||||||
- **«Тел: 2»** там, где ждёшь одно тело, — деталь распалась: касание объединением не считается
|
- **«Тел: 2»** там, где ждёшь одно тело, — деталь распалась: касание объединением не считается
|
||||||
(см. «Надписи»). Смотри на число ТЕЛ, а не граней: объединение сливает компланарные грани,
|
(см. «Надписи»). Смотри на число ТЕЛ, а не граней: объединение сливает компланарные грани,
|
||||||
и счётчик граней законно остаётся прежним.
|
и счётчик граней законно остаётся прежним.
|
||||||
|
**Но обратное неверно: «Тел: 1» распад не опровергает.** Счётчик в сводке ОПАЗДЫВАЕТ. Замер
|
||||||
|
(журнал операций кейса с хвостом по сечениям): `loft` построил второе тело и отчитался
|
||||||
|
«Тел: 1», следом `pattern(kind=mirror)` — снова «Тел: 1», и только третья операция, `chamfer_edge`, напечатала
|
||||||
|
«Тел: 2», хотя между ними ничего не создавалось. Три операции подряд шли по детали, объём
|
||||||
|
которой считал пересечение дважды. Поэтому «Тел: 2» — тревога, которой верят сразу, а «Тел: 1» —
|
||||||
|
не доказательство: там, где важно именно СРАСТАНИЕ (loft/sweep на грань, надпись, примитив
|
||||||
|
впритык), проверяй `describe_model(sections="bodies")` — у каждого тела там свой габарит — и сверяй
|
||||||
|
объём с прикидкой.
|
||||||
- **Объём сверяй с прикидкой** «площадь контура × высота». Так ловятся молча не применившаяся
|
- **Объём сверяй с прикидкой** «площадь контура × высота». Так ловятся молча не применившаяся
|
||||||
тонкая стенка (прирост как у сплошного сечения), вычитание мимо цели и операция «не туда» —
|
тонкая стенка (прирост как у сплошного сечения), вычитание мимо цели и операция «не туда» —
|
||||||
габарит и снимок этого не покажут.
|
габарит и снимок этого не покажут.
|
||||||
|
- **«⚠ Сверка с запросом: …»** — четвёртая, отдельная от первых трёх строка: сервер сравнил
|
||||||
|
результат с ВХОДНЫМИ параметрами вызова. Сейчас это положение материала у `extrude(mode=boss)`
|
||||||
|
и покрытие сечений у `loft(mode=boss)` (на базовых и смещённых плоскостях), убыль объёма у
|
||||||
|
`extrude(mode=cut)`, а у `primitive` — объём против номинала по его же размерам. Сработала —
|
||||||
|
построено не то, о чём просили, и в тексте сказано что именно. **Молчание успех НЕ доказывает**:
|
||||||
|
сверка односторонняя и намеренно молчит там, где улика неоднозначна (прирост меньше
|
||||||
|
запрошенного, материал целиком внутри габарита, эскиз выдавливания на грани, сечения лофта на
|
||||||
|
наклонной грани или с одинаковыми именами). Размер-выражение сверке не мешает: и у `primitive`,
|
||||||
|
и у `extrude` величина проверяется по уже вычисленному значению. Механика и границы —
|
||||||
|
`help(topic="build-verification")`.
|
||||||
|
|
||||||
Отдельный `describe_model(sections=errors,bodies,mass)` после каждого шага не нужен. Он
|
Отдельный `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`.
|
||||||
|
|
||||||
@@ -67,53 +115,12 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
намеренно не повторяется. Справочник описывает ЭТОТ сервер; справка по COM API КОМПАС — отдельная
|
намеренно не повторяется. Справочник описывает ЭТОТ сервер; справка по COM API КОМПАС — отдельная
|
||||||
история и в работе через MCP не нужна.
|
история и в работе через MCP не нужна.
|
||||||
|
|
||||||
## Инструменты: индекс групп
|
## Инструменты: где искать каталог
|
||||||
|
|
||||||
Актуальный перечень с описаниями параметров отдаёт сам MCP-сервер — здесь только карта:
|
Полный перечень инструментов с параметрами — `tools/list` самого MCP-сервера (единый источник
|
||||||
|
правды, держать вторую копию здесь не нужно). Что известно про
|
||||||
- *Система/документы:* `kompas_connect` (shared|private|attach), `kompas_set_visible`,
|
КОНКРЕТНЫЙ инструмент — `help(tool="extrude")`. Три сквозных свойства контракта, которые полезно
|
||||||
`kompas_status`, `set_auto_validate`, `set_operation_log`; `document_create|open|save|close`,
|
держать в голове, а не искать заново на каждом инструменте: **размерный параметр принимает число ИЛИ выражение** (имя
|
||||||
`document_active` (тип, путь, есть ли несохранённые изменения, «только чтение», материал детали),
|
|
||||||
`document_list` (все открытые документы — им проверяют, что имя файла занято другим документом
|
|
||||||
и что несохранённого не осталось), `set_part_info`, `set_part_material`.
|
|
||||||
- *Эскиз:* `sketch_create` (основание: `plane`+`offset` | `faceIndex` | точка; геометрия — списком
|
|
||||||
`entities` **или** файлом `entitiesFile`), `sketch_add`, `sketch_close`; `measure_text` — замер
|
|
||||||
надписи без построения; `fragment_create` — тот же список примитивов, но в самостоятельный
|
|
||||||
файл-фрагмент (*.frw); `fragment_place` — положить готовый фрагмент в чертёж.
|
|
||||||
- *Формообразующие:* `primitive`, `extrude`, `revolve`, `fillet_edge`, `chamfer_edge`, `shell`,
|
|
||||||
`rib`, `sweep`, `loft`, `draft`, `hole`, `pattern`, `mirror`, `feature_delete`, `rebuild`.
|
|
||||||
- *Прямое редактирование (в т.ч. импортированная B-rep):* `move_face`, `split_solid_by_plane`,
|
|
||||||
`move_body`, `boolean_union`.
|
|
||||||
- *Переменные:* `set_variable`, `list_parameters`, `link_parameter`, `delete_variable`
|
|
||||||
(сами переменные показывает `describe_model(sections=variables)`).
|
|
||||||
- *Обмен:* `import_model` (3D: step, iges, sat, xt, stl, c3d, jt, obj + родные форматы чужих САПР),
|
|
||||||
`import_drawing` (плоский .dxf/.dwg), `export_model` (`format=auto` по расширению: `.step` —
|
|
||||||
точная геометрия в другую САПР, `.stl` — сетка в слайсер).
|
|
||||||
- *Сборка:* `assembly_add_component` (положение + поворот `rx/ry/rz`), `assembly_add_mate`
|
|
||||||
(семь типов, `orientation`), `assembly_fix_component`, `assembly_delete`,
|
|
||||||
`assembly_check_interference` (не налезли ли детали друг на друга — больше это не видно нигде),
|
|
||||||
`assembly_transform_point` (`to=world|local` — точка между ЛСК компонента и СК сборки).
|
|
||||||
- *2D-чертёж:* `drawing_create_standard_views` (`views[]`, `mainOrientation`, `hiddenLines`),
|
|
||||||
`drawing_add_view` / `drawing_move_view` / `drawing_delete_view` / `drawing_get_view_info`
|
|
||||||
(компоновка листа и паспорт вида), `drawing_add_section_view` (РАЗРЕЗ или СЕЧЕНИЕ: линия разреза
|
|
||||||
на базовом виде и производный вид по ней — одним вызовом), `drawing_add_sheet`,
|
|
||||||
`drawing_set_sheet_format`,
|
|
||||||
`drawing_fill_title_block`,
|
|
||||||
`drawing_add_linear|diametral|radial|angular_dimension` (у всех — `tolerance`/`prefix`/`suffix`/
|
|
||||||
`textOverride`; у Ø и R — ещё `objectKind`/`objectIndex`, прямой адрес окружности или дуги),
|
|
||||||
`drawing_add_axis`, `drawing_add_rough|text|leader`,
|
|
||||||
`drawing_set_unspecified_rough`, `drawing_set_technical_requirements`, `drawing_delete_object`,
|
|
||||||
`drawing_move_object` (сдвинуть поставленное), `drawing_project_point` (точка модели → координаты
|
|
||||||
вида), `drawing_export_image` (посмотреть
|
|
||||||
глазами). Обратное чтение — `drawing_get_title_block` и `drawing_get_technical_requirements`:
|
|
||||||
технические требования ПЕРЕЗАПИСЫВАЮТСЯ целиком, поэтому правку одного пункта начинают с чтения
|
|
||||||
текущего текста. Методика — §«Чертёж».
|
|
||||||
- *Осмотр:* `describe_model` (разделы `box|mass|bodies|topology|tree|variables|errors|components|mates` —
|
|
||||||
габарит, МЦХ, тела, топология, дерево построения, переменные, операции в ошибке, состав сборки,
|
|
||||||
сопряжения), `measure`, `model_snapshot`; адресация объектов — `list_faces` / `list_edges`.
|
|
||||||
Для 2D-документов — свой: `list_drawing_objects` (что лежит в чертеже/фрагменте).
|
|
||||||
|
|
||||||
Три сквозных свойства контракта: **размерный параметр принимает число ИЛИ выражение** (имя
|
|
||||||
переменной/формулу — параметр сразу становится ведомым); **объект выбирается индексом** (надёжно)
|
переменной/формулу — параметр сразу становится ведомым); **объект выбирается индексом** (надёжно)
|
||||||
или точкой (запасной путь — если выбирал точкой, ответ подскажет, что выбралось); **списковые
|
или точкой (запасной путь — если выбирал точкой, ответ подскажет, что выбралось); **списковые
|
||||||
параметры** (`entities[]`, `edgeIndices[]`, `points[]`, `faceIndices[]`, `variables[]`, `links[]`) —
|
параметры** (`entities[]`, `edgeIndices[]`, `points[]`, `faceIndices[]`, `variables[]`, `links[]`) —
|
||||||
@@ -124,6 +131,14 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
остаётся — повторяй вызов с оставшимися, а не с начала. Если инструмента под задачу нет — собирай
|
остаётся — повторяй вызов с оставшимися, а не с начала. Если инструмента под задачу нет — собирай
|
||||||
результат из имеющихся общих операций.
|
результат из имеющихся общих операций.
|
||||||
|
|
||||||
|
**Оговорка для больших групп рёбер в `fillet_edge`/`chamfer_edge`.** «Один вызов на весь пакет»
|
||||||
|
экономит вызовы, но у катета/радиуса есть рабочий диапазон, заданный ВСЕЙ группой рёбер разом, а
|
||||||
|
не отдельным ребром (измерено: один и тот же контур строится с меньшим катетом и отказывает с
|
||||||
|
большим). Параметрическая модель может пройти это на одном значении переменной и отказать на
|
||||||
|
другом — большая группа сама по себе фактор хрупкости при последующей правке размеров. Если пакет
|
||||||
|
на 15+ рёбер отказывает без диагноза по длине, разбейте его на 2–3 группы — сервер сам подскажет
|
||||||
|
это в тексте отказа (`help(topic="edge-groups")`).
|
||||||
|
|
||||||
## Два пути формообразования — выбирай по форме, а не по привычке
|
## Два пути формообразования — выбирай по форме, а не по привычке
|
||||||
|
|
||||||
«Эскиз → выдавливание» — не единственный способ. `primitive` строит тело сразу по размерам, и это
|
«Эскиз → выдавливание» — не единственный способ. `primitive` строит тело сразу по размерам, и это
|
||||||
@@ -134,7 +149,9 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
| Плита, брусок, бобышка, штифт, цилиндрическая стойка | `primitive(kind=block\|cylinder)` — один вызов вместо «эскиз + выдавливание» |
|
| Плита, брусок, бобышка, штифт, цилиндрическая стойка | `primitive(kind=block\|cylinder)` — один вызов вместо «эскиз + выдавливание» |
|
||||||
| Прямоугольный карман, паз, срез угла | `primitive(..., result=subtract)` — вычитание тела вместо `extrude(mode=cut)` по эскизу |
|
| Прямоугольный карман, паз, срез угла | `primitive(..., result=subtract)` — вычитание тела вместо `extrude(mode=cut)` по эскизу |
|
||||||
| Скруглённые углы призмы | `primitive` + `fillet_edge` по рёбрам (скругление после, а не дуги в эскизе) |
|
| Скруглённые углы призмы | `primitive` + `fillet_edge` по рёбрам (скругление после, а не дуги в эскизе) |
|
||||||
| Текст, кривые, произвольный контур, переменное сечение | ТОЛЬКО эскиз: `sketch_create(entities=[…])` + `extrude`/`revolve`/`loft`/`sweep` |
|
| Текст, кривые, произвольный контур | ТОЛЬКО эскиз: `sketch_create(entities=[…])` + `extrude`/`revolve` |
|
||||||
|
| Переменное сечение: хвост, гребень, переход круга в квадрат | `loft` по сечениям на смещённых плоскостях (`mode=boss` приклеивает к телу) |
|
||||||
|
| Труба, поручень, кант по кривой | `sweep(profileSketchId, pathSketchId)` — профиль и траектория на разных плоскостях |
|
||||||
| Тонкая стенка, ободок по контуру | эскиз + `extrude(thinThickness, thinSide)` |
|
| Тонкая стенка, ободок по контуру | эскиз + `extrude(thinThickness, thinSide)` |
|
||||||
|
|
||||||
Их **сочетают в одной детали**: корпусные объёмы — примитивами, сложные контуры — эскизами.
|
Их **сочетают в одной детали**: корпусные объёмы — примитивами, сложные контуры — эскизами.
|
||||||
@@ -156,14 +173,32 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
координат — одна операция на все; точки без ребра ошибка перечислит разом.
|
координат — одна операция на все; точки без ребра ошибка перечислит разом.
|
||||||
- **Скругление не построится там, где ребро «съедено» соседним элементом** (угол плашки под каймой
|
- **Скругление не построится там, где ребро «съедено» соседним элементом** (угол плашки под каймой
|
||||||
букв). Это нормальный ответ геометрии, а не ошибка вызова: проверь снимком, виден ли угол снаружи.
|
букв). Это нормальный ответ геометрии, а не ошибка вызова: проверь снимком, виден ли угол снаружи.
|
||||||
|
- **Фаска на почти касательном стыке может ДОСТРОИТЬ объём, а не срезать.** Замер: `chamfer_edge`
|
||||||
|
0.3 по кромке, где поверхность лофта сходит в плоскость почти по касательной, — «построение
|
||||||
|
чистое», а объём ВЫРОС на 2.2 мм³. На выпуклом ребре фаска обязана объём УМЕНЬШАТЬ (на вогнутом
|
||||||
|
легитимно добавляет); сверяй ЗНАК приращения в сводке ответа со своим ожиданием — вырос без
|
||||||
|
причины, значит фаска выродилась в достройку: убери её `feature_delete`, пологому стыку она
|
||||||
|
и не нужна.
|
||||||
- **`result=new` даёт ОТДЕЛЬНОЕ тело**, `subtract` мимо цели сервер ловит сам — и то и другое
|
- **`result=new` даёт ОТДЕЛЬНОЕ тело**, `subtract` мимо цели сервер ловит сам — и то и другое
|
||||||
видно по сводке «Тел/объём» в ответе; при распаде зови `boolean_union`.
|
видно по сводке «Тел/объём» в ответе; при распаде зови `boolean`.
|
||||||
|
- **Сужающуюся или изогнутую форму не набирай лесенкой из примитивов.** `primitive` не умеет
|
||||||
|
поворота, и «хвост» из десятка блоков со ступеньками — это обход отсутствующего инструмента,
|
||||||
|
а не решение: он и печатается хуже, и правится только целиком. Бери `loft` по 4–6 сечениям на
|
||||||
|
смещённых плоскостях — параметричность не теряется, `offset` плоскости принимает выражение.
|
||||||
|
**`loft` может отказать молча, и отказ зависит от ПРОЛЁТА, а не от одного сечения** — поиск
|
||||||
|
виновника перебором пар не работает, ломается СОЧЕТАНИЕ «сечение-выброс + длина набора»; механика
|
||||||
|
и порядок поиска — `help(topic="loft-and-sweep")`.
|
||||||
|
- **`loft(mode=boss)` прирастает перекрытием, а не касанием.** Первое сечение ставь на плоскость
|
||||||
|
ВНУТРИ уже построенного тела (смещение на 1–2 мм вглубь), а не на его грань: касание объединением
|
||||||
|
не считается — на грани получишь ВТОРОЕ тело вместо приросшего. **Проверять это сводкой «Тел: 1»
|
||||||
|
НЕЛЬЗЯ** — именно здесь она и соврала (см. правило 2): считай тела
|
||||||
|
`describe_model(sections="bodies")`, там у каждого свой габарит, и сверь объём с прикидкой.
|
||||||
|
|
||||||
## Базовый цикл (эскиз → операция → осмотр)
|
## Базовый цикл (эскиз → операция → осмотр)
|
||||||
|
|
||||||
Опорный сценарий построения, проверен end-to-end:
|
Опорный сценарий построения, проверен 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. **Запиши замысел переменными** до первого эскиза (см. «Параметризация») и связывай каждый
|
||||||
@@ -172,7 +207,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`) — безликая «Деталь» уедет в штамп
|
||||||
@@ -189,28 +224,37 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
пересборки. Набор переменных — это план построения числами и паспорт, по которому человек поймёт
|
пересборки. Набор переменных — это план построения числами и паспорт, по которому человек поймёт
|
||||||
модель, не разбирая дерево.
|
модель, не разбирая дерево.
|
||||||
|
|
||||||
- **Заводи переменной то, что было РЕШЕНИЕМ**: габариты из ТЗ, толщины, зазоры, отступы, кегли,
|
- **Заводи переменной то, что было РЕШЕНИЕМ** (габариты из ТЗ, толщины, зазоры), позиции, подобранные
|
||||||
радиусы. Выводимое задавай формулой (`plate_L = badge_L - 2*edge_gap`) — правка ведущего размера
|
замером, оставляй числами; **размер передавай выражением прямо в операцию**
|
||||||
пересчитает зависимые сама. Позиции, подобранные замером, оставляй числами: связь — обещание,
|
(`extrude(depth="badge_T")`) — переменная должна существовать ДО операции.
|
||||||
что правка переменной даст осмысленный результат, а на позиционных числах она чаще ломает деталь.
|
- **После связывания правка паспорта перестраивает деталь; до связывания — нет**, и `set_variable`
|
||||||
- **Размер передавай выражением прямо в операцию** (`extrude(depth="badge_T")`) — параметр сразу
|
прямо говорит «⚠ НИЧЕГО НЕ ВЕДЁТ» в этом случае — не успех, хоть число и поменялось.
|
||||||
становится ведомым, внутреннее имя параметра («Расстояние 1») знать не нужно. Переменная должна
|
- **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт»;
|
||||||
существовать ДО операции — потому паспорт и заводят первым. Задним числом и для параметров,
|
`delete_variable(unused=true)` не трогает справочные (`information`) и внешние.
|
||||||
которых нет среди аргументов инструмента (углы уклона, второе направление), — `link_parameter`.
|
- **Проверь крайние значения переменных ДО прогона.** Размер, зависящий от модуля или шага, но
|
||||||
- **Промахи сервер ловит сам:** ссылка на несуществующее имя — отказ с перечнем виновных (и в
|
заданный числом, ломает модель на соседнем значении (обод Ø178 при m=4 оказывается шире
|
||||||
выражениях операций, и в `set_variable`; регистр значим), функции в формулах — предупреждение
|
вершин Ø172 — профиль самопересекается). Веди такие размеры от той же переменной.
|
||||||
(тригонометрия в радианах, разделитель аргументов «;», непонятая запись = молчаливый 0).
|
- **Галтель, скругление угла профиля** — примитив `{type:"fillet", between:[i, j], radius}` на
|
||||||
Твоя часть — **сверить вычисленные значения из ответа со своей прикидкой**.
|
острый угол двух отрезков или дуг: точное сопряжение находит решатель КОМПАС, считать точки
|
||||||
- **`note` обязателен** и пишется по-русски, со смыслом и единицей; `(ТЗ)` метит числа,
|
касания не нужно (`help(topic="sketch-entities")`). Радиус ведёт переменная — `radius` на номер
|
||||||
зафиксированные пользователем. **Что замерил — верни в переменную** (фактический кегль, прирост
|
`fillet` в `dimensions`. Если две галтели по данным сходятся в одну (центр уходит за ось
|
||||||
каймы), иначе паспорт разойдётся с моделью и станет дезинформацией. Переосмысливать можно всё,
|
симметрии, дуги дна между ними нет) — один `fillet` прямо между двумя боковыми дугами.
|
||||||
кроме помеченного `(ТЗ)`.
|
- **Паз со сбегом по дуге** (выход дисковой фрезы): прорежь паз `extrude(cut)` с перебегом за
|
||||||
- **После связывания правка паспорта перестраивает деталь** (проверено: `set_variable(badge_T=4)` →
|
место сбега, затем верни лишнее `revolve(boss)` профиля, ограниченного дугой сбега, вокруг оси
|
||||||
габарит по Z 3.00 → 4.00, объём 5154.5 → 5861.5 мм³). Это и есть параметрическая модель,
|
вала; либо `revolve(cut)` сечения паза вокруг оси фрезы. У `extrude` нет переменного дна.
|
||||||
а не комментарий к ней.
|
- **Фаски и скругления на кромках зубчатого венца — ДО нарезки зубьев:** одно круговое ребро
|
||||||
- **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт» — это либо забытая
|
заготовки вращения вместо десятков рёбер после массива (иначе их перечисляют индексами).
|
||||||
связь, либо мусор; разбери оба. `delete_variable(unused=true)` — только ПОСЛЕ `link_parameter`
|
- **Профиль вала вдоль 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).
|
||||||
|
|
||||||
## Надписи, логотипы и рельеф
|
## Надписи, логотипы и рельеф
|
||||||
|
|
||||||
@@ -232,269 +276,99 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
- **Надпись и плашка обязаны ПЕРЕКРЫВАТЬСЯ** — по размерам чертежа блоки обычно только касаются,
|
- **Надпись и плашка обязаны ПЕРЕКРЫВАТЬСЯ** — по размерам чертежа блоки обычно только касаются,
|
||||||
а касание объединением не считается. Приём: кайму/полосу плашки сделать выше самой плашки на
|
а касание объединением не считается. Приём: кайму/полосу плашки сделать выше самой плашки на
|
||||||
1–1.5 мм с той стороны, где стоит надпись. Распад видно по «Тел: 2» в ответе операции — не тяни
|
1–1.5 мм с той стороны, где стоит надпись. Распад видно по «Тел: 2» в ответе операции — не тяни
|
||||||
проверку до конца построения.
|
проверку до конца построения. Молчание сводки распад не опровергает (счётчик опаздывает, п. 2):
|
||||||
|
убедиться, что срослось, можно только `describe_model(sections="bodies")`.
|
||||||
- **Рельеф = разница глубин от одной плоскости** (основание 2 мм + буквы 3 мм = выступ 1 мм);
|
- **Рельеф = разница глубин от одной плоскости** (основание 2 мм + буквы 3 мм = выступ 1 мм);
|
||||||
не строй буквы «на грани основания» — из одного эскиза на базовой плоскости получается и то и
|
не строй буквы «на грани основания» — из одного эскиза на базовой плоскости получается и то и
|
||||||
другое, и рельеф не зависит от порядка операций.
|
другое, и рельеф не зависит от порядка операций.
|
||||||
|
- **Надпись читается только с той стороны, куда смотрит нормаль плоскости эскиза** — XOY → +Z,
|
||||||
|
XOZ → +Y, **YOZ → −X**. Гравировка по эскизу на YOZ, положенная на грань с бОльшим X, выходит
|
||||||
|
ЗЕРКАЛЬНОЙ, и `angle` этого не исправляет: он вращает, а не отражает (замер — цифра на щеке
|
||||||
|
X=20.4 зеркальна при любом угле, тот же эскиз на X=0 встаёт верно). Выбирайте грань по нормали,
|
||||||
|
а поворотом задавайте только, куда смотрит верх глифа. Проверять — снимком С ТОЙ СТОРОНЫ, где
|
||||||
|
надпись будет видна: `model_snapshot(view=left)` для грани X=0, `right` для X=max.
|
||||||
- **Шрифт должен быть установлен в системе** — неизвестное имя КОМПАС молча подменяет; сервер
|
- **Шрифт должен быть установлен в системе** — неизвестное имя КОМПАС молча подменяет; сервер
|
||||||
предупреждает об этом в ответе `sketch_create`/`measure_text` — не игнорируй.
|
предупреждает об этом в ответе `sketch_create`/`measure_text` — не игнорируй.
|
||||||
|
|
||||||
**Логотип, которого нет в шрифте, приходит готовым вектором (SVG).** Переводи его в примитивы
|
**Логотип (SVG) и выбор маршрута для внешнего контура (вычисляемый / срисованный / CAD-файл) —
|
||||||
эскиза сам — `line` и `arc3points`, а не ломаной: контур из сотен звеньев даёт деталь в сотни
|
в [reference/text-and-relief.md](reference/text-and-relief.md).** Там же — точная подгонка (кегль
|
||||||
граней, и фаска по такому низу не строится. Кубические Безье режь пополам, пока дуга по трём
|
под заданную ширину, ступени `widthFactor`/`height`, приросты каймы на острых терминалах, разрядка
|
||||||
точкам не ляжет в допуск. Четыре вещи, каждая из которых стоила захода:
|
пробелами, кайма вокруг прямоугольной плашки) и отделка рельефа (скругления/фаски на сотнях рёбер).
|
||||||
|
Прочитай его, как только контур не сводится к простому вычисляемому эскизу.
|
||||||
|
|
||||||
- **Ось Y в SVG смотрит вниз** — без инверсии контур встаёт вверх ногами, и это видно только на снимке.
|
Фрагмент (*.frw, самостоятельный файл переиспользуемого контура/чертежа) —
|
||||||
- **Дуги задавай тремя точками** (`arc3points`): концы заданы явно, соседние примитивы стыкуются
|
[reference/fragments.md](reference/fragments.md).
|
||||||
точно. Перед постройкой проверь цепочку — конец примитива против начала следующего, разрыв 0.
|
|
||||||
- **Чисти мелочь под масштаб детали — параметром `minSegment`.** SVG рисуют в своём габарите (сотня
|
|
||||||
условных единиц), и его скругления после масштабирования превращаются в дуги по 0.02–0.5 мм;
|
|
||||||
замыкающий `z` часто даёт ещё и сегмент нулевой длины. `chamfer_edge` по такому набору отвечает
|
|
||||||
«катет больше длины N из M рёбер» — и это правда. Передай `sketch_create(minSegment=катет)` (тот же
|
|
||||||
параметр есть у `sketch_update` и `fragment_create`), и та же фаска пройдёт с первой попытки;
|
|
||||||
отчёт о выброшенном читай, а не пролистывай — `help(topic="contour-cleanup")`.
|
|
||||||
|
|
||||||
**Порядок для фаски по контуру логотипа — только такой, и он неочевиден:**
|
## Раскраска: умеренно и по смыслу
|
||||||
|
|
||||||
1. **чистка** порогом ≈ будущего катета (`minSegment`);
|
Цвет — последний шаг, после геометрии: `set_appearance` её не трогает и в дереве узлов не
|
||||||
2. **замер ЧИЩЕНОГО силуэта** — `sketch_measure_thickness(entitiesFile, minSegment=тот же порог)`;
|
плодит. Задача раскраски — чтобы модель читалась с первого взгляда, а не чтобы она была пёстрой.
|
||||||
3. **катет по узкому месту** чищеного силуэта: `c ≤ (узкое_место − 2·w)/2`, где `w` — ширина нити.
|
|
||||||
|
|
||||||
Менять шаги местами нельзя: **чистка СУЖАЕТ узкое место**. Она заменяет скругление острым углом —
|
- **Одна основа, один-два акцента.** Деталь целиком — спокойный нейтральный цвет
|
||||||
в выпуклом углу это добавляет материал (габарит подрастает), а в вогнутом срезает его, и именно
|
(`target="part"`), акцент — тому, что должно бросаться в глаза: надпись, логотип, кнопка,
|
||||||
вогнутые углы образуют перемычки между штрихами. Замер обводки логотипа шириной 105 мм:
|
посадочная поверхность. Три и больше акцентов уже шумят.
|
||||||
узкое место 1.98 → 1.82 мм, порог распада лицевой грани 0.99 → 0.91. Катет, подобранный по
|
- **Надпись и логотип красятся ОПЕРАЦИЕЙ**, которая их выдавила
|
||||||
нечищеному контуру, после чистки перестаёт проходить свой же критерий.
|
(`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`.
|
||||||
|
|
||||||
- **Ширину штриха и узкое место меряй инструментом, а не глазом** — `sketch_measure_thickness`
|
Механизм, имена цветов и измеренные факты — `help(topic="appearance")`.
|
||||||
ничего не строит и документа не требует, поэтому зовётся ДО эскиза
|
|
||||||
(`help(topic="silhouette-thickness")`). От этих чисел зависит, останется ли что-то от рисунка
|
|
||||||
после фаски и напечатается ли он вообще; шаг растра в ответе — точность округления катета.
|
|
||||||
|
|
||||||
Контур, который переживёт конкретную деталь (логотип, шаблон, профиль), клади во фрагмент —
|
|
||||||
`fragment_create(path, entities)` тем же списком примитивов. Активный документ он не подменяет,
|
|
||||||
поэтому фрагмент можно снять посреди построения детали; габарит в ответе снят с самого документа —
|
|
||||||
сверяй его с задуманным.
|
|
||||||
|
|
||||||
**Точная подгонка и отделка — в [reference/text-and-relief.md](reference/text-and-relief.md);
|
|
||||||
прочитай его, как только доходишь до точной компоновки надписи или отделки рельефа:** подбор кегля
|
|
||||||
под заданную ширину за одну пробу, ступени `widthFactor`/`height`, приросты каймы на острых
|
|
||||||
терминалах (t/sin(θ/2)) и её роль в стыковке блоков, разрядка пробелами, кайма вокруг прямоугольной
|
|
||||||
плашки, карманы `primitive(subtract)` рядом с буквами, скругления и фаски рельефа на сотнях рёбер.
|
|
||||||
|
|
||||||
## Внешний контур: не диктуй координаты, если фигуру нельзя описать формулой
|
|
||||||
|
|
||||||
Три маршрута, и выбор между ними механический — не по вкусу, а по происхождению геометрии.
|
|
||||||
|
|
||||||
| Откуда фигура | Чем строить |
|
|
||||||
|---|---|
|
|
||||||
| **Вычисляется**: пластины, рёбра, сетка отверстий | `sketch_create(entities[])` — прямо в вызове, размеры вяжи переменными |
|
|
||||||
| **Срисована**: логотип, шаблон, кулачок, профиль | внешний вектор → JSON → `sketch_create(entitiesFile=…)` |
|
|
||||||
| **Пришла в CAD-формате**: файл от смежника | `import_drawing` (.dxf/.dwg) → фрагмент → `fragment_place` |
|
|
||||||
|
|
||||||
**Обводка занимает сотни примитивов, и переписывать их в тело вызова незачем.** У `sketch_create`,
|
|
||||||
`sketch_add` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`;
|
|
||||||
сервер читает файл сам. Замер на эмблеме Volvo: SVG в 1.5 КБ даёт 96 примитивов (50 отрезков +
|
|
||||||
46 дуг) и 9.5 КБ JSON; через `entitiesFile` это один вызов на одну строку аргументов, а эскиз
|
|
||||||
строится за один заход. Оба параметра можно задать вместе — сначала `entities`, следом файл:
|
|
||||||
так к готовому контуру дописывают рамку или ось, не трогая файл.
|
|
||||||
|
|
||||||
Что проверить **до** постройки, а не после: габарит в ответе (`fragment_create` печатает
|
|
||||||
фактический — сверь с задуманным) и вложенные контуры. Правил заливки у эскиза КОМПАС нет: любой
|
|
||||||
вложенный контур он режет как отверстие, даже там, где вектор заливал материал. Конвертер такие
|
|
||||||
места называет заранее — на них смотри до выдавливания, иначе дыры обнаружатся на снимке.
|
|
||||||
|
|
||||||
## Фрагмент — переиспользуемый чертёж, а не сечение
|
|
||||||
|
|
||||||
Эскиз живёт внутри дерева построения и вне его не существует; фрагмент (*.frw) — самостоятельный
|
|
||||||
файл, который переживает деталь. `fragment_create` его пишет, `fragment_place` кладёт в активный
|
|
||||||
чертёж или другой фрагмент, а `mode` решает, чем он там станет — и это разные объекты, а не
|
|
||||||
оттенки одного:
|
|
||||||
|
|
||||||
- **`reference`** — вставка-ссылка: содержимым владеет файл, правка файла меняет все документы, куда
|
|
||||||
он вставлен. Ради этого фрагменты и заводят: одна заготовка на десять чертежей.
|
|
||||||
- **`copy`** — копия внутри документа, живёт своей жизнью; файл потом можно удалить.
|
|
||||||
- **`local`** — вставка, переиспользуемая только внутри этого документа.
|
|
||||||
- **`explode`** — россыпь обычных примитивов: правится по одному, но связи с файлом уже нет.
|
|
||||||
|
|
||||||
`angle` (градусы), `scale` и `mirror` задают размещение; зеркалить можно только вставку — у россыпи
|
|
||||||
отражать нечего. **Зеркало отражает относительно вертикали через точку вставки**, поэтому контур
|
|
||||||
уходит в другую сторону от неё: вставка в x=220 после `mirror` занимает 160…220, а не 220…280.
|
|
||||||
|
|
||||||
Проверять результат — `list_drawing_objects`: он показывает состав по типам, габарит и все вставки
|
|
||||||
с их файлами. Вставка, чей файл потерялся, рисуется пустым местом — в списке она помечена
|
|
||||||
недействительной, и это единственный способ отличить её от удавшейся, не глядя на экран.
|
|
||||||
|
|
||||||
## Сборка: собрать своё
|
## Сборка: собрать своё
|
||||||
|
|
||||||
Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.**
|
Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.**
|
||||||
Разбор чужой сборки — следующий раздел, здесь про сборку с нуля.
|
Сборка с нуля целиком, с адресацией граней, семью типами сопряжений и порядком проверки —
|
||||||
|
[reference/assembly-playbook.md](reference/assembly-playbook.md). Разбор чужой сборки (пришедшей
|
||||||
1. **Детали сначала сохрани в файлы.** Компонент вставляется ссылкой на `.m3d`/`.a3d`, поэтому
|
STEP/импортом) — следующий раздел.
|
||||||
несохранённую деталь вставить нельзя.
|
|
||||||
2. **`document_create assembly` → `assembly_add_component(filePath, x, y, z, rx, ry, rz)`.** Углы — в
|
|
||||||
градусах, вокруг СОБСТВЕННЫХ осей компонента и по очереди X→Y→Z: второй угол считается уже от
|
|
||||||
повёрнутого положения. Пока задан один угол, разницы с мировыми осями нет.
|
|
||||||
3. **Зафиксируй базовую деталь СРАЗУ: `assembly_fix_component(componentIndex=0, fixedState=true)`.** КОМПАС не закрепляет
|
|
||||||
никого сам, включая первый компонент, и решатель двигает того, кого сочтёт нужным — в том числе
|
|
||||||
основание, вокруг которого ты собираешь всё остальное. Это самая частая причина «сопряжение
|
|
||||||
верное, а сборка расползлась».
|
|
||||||
4. **Сопрягай:** `assembly_add_mate(mateType, …)` — семь типов, адресация гранью и смысл
|
|
||||||
`orientation` в `help(topic="assembly-mates")`. Что решаешь ты, а не справочник:
|
|
||||||
- **Грань адресуй индексом, а не координатами:** `list_faces(component=N)` → пара
|
|
||||||
`faceIndex`+`componentIndex`. Точки на бумаге считать не нужно, и сервер сам проверит, что
|
|
||||||
грань принадлежит этому компоненту.
|
|
||||||
- **Сторону зазора у `distance` задаёт ВЫБОР ПАРЫ ГРАНЕЙ, и от стартового положения она не
|
|
||||||
зависит.** «Closest» — не «ближайшее»: при сонаправленных нормалях объект 1 садится со стороны
|
|
||||||
−n относительно объекта 2 (замерено двойным прогоном). Практическое правило: бери пару граней,
|
|
||||||
которые смотрят ДРУГ НА ДРУГА. Вышло зеркально — меняй грань, а не `orientation`.
|
|
||||||
- **Первое сопряжение вешай на зафиксированную деталь.** Пока в цепочке нет ни одного
|
|
||||||
закреплённого звена, решатель волен двигать любое; связка «каждый новый компонент — к уже
|
|
||||||
стоящему на месте» разваливается вдвое реже, чем связка «все ко всем».
|
|
||||||
5. **`rebuild`,** если авто-валидация написала «ℹ Требуется перестроение». Это НЕ ошибка построения:
|
|
||||||
так помечает себя свежий компонент или только что наложенная связь. Бросать работу здесь не надо
|
|
||||||
— правило «не продолжай при ⚠» касается строки со знаком ⚠, а не этой.
|
|
||||||
**Исключение из правила «⚠ = стоп».** После КАЖДОГО сопряжения авто-валидация пишет
|
|
||||||
«⚠ N операц. в ошибке: „Сопряжения“ (код 0: ошибки нет)». Это то же «требуется перестроение»,
|
|
||||||
только под знаком ⚠: код 0 и имя операции «Сопряжения» означают, что ломаться нечему. Делай
|
|
||||||
`rebuild` и иди дальше. Настоящая беда со связью видна не здесь, а в
|
|
||||||
`describe_model(sections=mates)` — по пометке `valid:false`.
|
|
||||||
6. **Проверь:**
|
|
||||||
- `describe_model(sections=components)` — origin, поворот ЧИСЛАМИ (`rx/ry/rz` в градусах, та же
|
|
||||||
семантика, что у вставки) и «зафиксирован/свободен» у каждого: этим и видно, КОГО и НА СКОЛЬКО
|
|
||||||
подвинул решатель;
|
|
||||||
- `describe_model(sections=mates)` — что с чем связано, с каким значением и не выродилось ли.
|
|
||||||
Это ключевой детектор: `assembly_add_mate` может ответить успехом, а связь окажется
|
|
||||||
вырожденной;
|
|
||||||
- `measure(kind1=face, index1=…, componentIndex1=…, kind2=face, index2=…, componentIndex2=…)` —
|
|
||||||
зазор между деталями напрямую, без арифметики по габаритам;
|
|
||||||
- `assembly_check_interference(componentIndex1, componentIndex2)` — **не налезли ли детали друг
|
|
||||||
на друга.** Проверяй все пары, которые должны идти впритирку.
|
|
||||||
|
|
||||||
**Неудачную связь не нужно пересобирать с нуля:** `assembly_delete(target="mate"|"component", index)`
|
|
||||||
снимает сопряжение или компонент вместе с опирающимися на него связями. Индексы после удаления
|
|
||||||
сдвигаются — иди от больших к меньшим и перечитывай `describe_model(sections=mates)`.
|
|
||||||
|
|
||||||
**Пересечение деталей не видно НИГДЕ, кроме `assembly_check_interference`.** Сборка складывается из
|
|
||||||
готовых тел, и КОМПАС их не вычитает: две детали могут занимать общий объём, а сопряжения при этом
|
|
||||||
останутся `valid`, раздел `errors` — пустым, объём экспорта — простой суммой компонентов. `measure`
|
|
||||||
тоже не спасает: нулевой зазор одинаково означает и касание, и взаимопроникновение. Проверяй все
|
|
||||||
пары, которые должны идти впритирку.
|
|
||||||
|
|
||||||
**«Тела: 0» в сборке означает не «пусто», а «спрошено не то»:** тела принадлежат компонентам
|
|
||||||
(`describe_model(component=N, …)`), а `box` и `mass` без `component` честно дают габарит и МЦХ сборки
|
|
||||||
целиком. Про разные системы координат внутри паспорта компонента —
|
|
||||||
`help(topic="model-inspection")`; про локальные координаты граней и `pointOnFace` —
|
|
||||||
`help(topic="face-addressing")`.
|
|
||||||
|
|
||||||
## Чертёж: оформить деталь по ГОСТ
|
## Чертёж: оформить деталь по ГОСТ
|
||||||
|
|
||||||
Чертёж строится не так, как деталь: **авто-валидации здесь нет**. Правило трёх проверок из §«Базовый
|
Чертёж строится не так, как деталь: **авто-валидации здесь нет** — верность тут не про геометрию,
|
||||||
цикл» в 2D не работает — операция не отчитывается «построилось верно», потому что верность тут не
|
а про место на листе, и проверяется только просмотром. Порядок «формат → виды → координаты замером
|
||||||
про геометрию, а про место на листе. Проверять приходится самому, и способ ровно один: посмотреть.
|
→ разрез до размеров → простановка → `drawing_export_image`», разрез, три ловушки, на которых
|
||||||
|
чертёж молча выходит неверным (`viewNumber=0`, ассоциативность размеров, допуск без read-back), и
|
||||||
**Порядок, который окупается:**
|
чего в 2D нет — [reference/drawing-playbook.md](reference/drawing-playbook.md).
|
||||||
|
|
||||||
1. **Деталь строится в чертёжной ориентации.** Набор видов задаётся ОТ модели: `mainOrientation`
|
|
||||||
выбирает, какую ориентацию модели показывает главный вид, но саму ориентацию модели он не
|
|
||||||
вращает. Если самая информативная проекция детали — не одна из шести стандартных, чертежа по
|
|
||||||
ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость
|
|
||||||
с наибольшей информацией.
|
|
||||||
2. **`drawing_set_sheet_format`** (формат до видов — иначе виды придётся двигать), при
|
|
||||||
необходимости `drawing_add_sheet` для второго листа.
|
|
||||||
3. **`drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…)`** — бери ровно те
|
|
||||||
проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. **Главный вид
|
|
||||||
входит в набор сам**: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому `views=["top"]`
|
|
||||||
даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими.
|
|
||||||
4. **Координаты — замером, а не формулой.** `drawing_get_view_info(viewNumber)` отдаёт паспорт вида
|
|
||||||
одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает
|
|
||||||
начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось
|
|
||||||
проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид
|
|
||||||
арифметикой; отдельные точки переводит `drawing_project_point(x, y, z, viewNumber)`.
|
|
||||||
Выводить оси из головы не надо и вредно: у КОМПАС «спереди» показывает плоскость XY детали, а
|
|
||||||
«сверху» — X и **минус Z**, и **знаки инверсии зависят от `mainOrientation`** — формула,
|
|
||||||
выведенная на одном чертеже, на соседнем врёт.
|
|
||||||
5. **Разрез — до размеров, а не после.** Внутреннюю геометрию (зенковка, ступенчатое отверстие,
|
|
||||||
паз, глубокая расточка, полость) показывай разрезом, а не невидимыми линиями: по штриховой линии
|
|
||||||
нельзя ни поставить нормальный размер, ни разобрать форму. `drawing_add_section_view` — см.
|
|
||||||
§«Разрез» ниже. Размеры внутренней геометрии ставятся УЖЕ НА РАЗРЕЗЕ, поэтому строить его надо
|
|
||||||
раньше простановки, иначе размеры придётся переносить.
|
|
||||||
6. **Размеры**, `drawing_add_axis` (осевые и центровые), шероховатость, выноски, техтребования,
|
|
||||||
штамп. **Осевые сначала посмотри, потом добивай**: ассоциативные виды приходят со СВОИМИ
|
|
||||||
центровыми и осевыми, которые КОМПАС ставит сам, и `drawing_add_axis` вслепую даёт дубли поверх
|
|
||||||
существующих. Сначала `list_drawing_objects(kind="axis"|"centreMarker", viewNumber=…)`.
|
|
||||||
7. **`drawing_export_image`** — посмотреть глазами. Пока картинки не было, чертёж не сдан.
|
|
||||||
|
|
||||||
### Разрез
|
|
||||||
|
|
||||||
`drawing_add_section_view` делает всё сразу: проводит линию разреза на базовом виде и строит по ней
|
|
||||||
производный вид со штриховкой. Механика, ступенчатый разрез и встроенная проверка честности —
|
|
||||||
`help(topic="drawing-sections")`; здесь только решения, которые принимаешь ты:
|
|
||||||
|
|
||||||
- **Разрез или `hiddenLines`.** Разрез — когда внутреннее нужно ИЗМЕРИТЬ или показать форму:
|
|
||||||
зенковка и цековка, ступенчатое или резьбовое отверстие, паз, канавка, глубокая расточка, тонкая
|
|
||||||
стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к
|
|
||||||
штриховой линии не привязывают.
|
|
||||||
- **Веди линию с запасом за габарит** (плита 60 мм → от −40 до +40): линия по самому краю режет не
|
|
||||||
всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `drawing_get_view_info`.
|
|
||||||
- **Строй разрез, когда модель готова**: после правки детали перестраивается только ПЕРВЫЙ разрез
|
|
||||||
базового вида. Модель всё же изменилась — снеси разрезы и построй заново.
|
|
||||||
- Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру.
|
|
||||||
|
|
||||||
**Промах простановки лечится, а не остаётся навсегда.** Отката (undo) у чертежа нет, но
|
|
||||||
`list_drawing_objects` показывает обозначения с индексами, `drawing_delete_object` убирает одно, а
|
|
||||||
`drawing_move_object` его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не
|
|
||||||
заменой размера на выноску. Так же правится и компоновка: `drawing_move_view` переставляет вид со
|
|
||||||
всеми обозначениями, `drawing_add_view` доносит недостающую проекцию, `drawing_delete_view` убирает
|
|
||||||
лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления —
|
|
||||||
`help(topic="drawing-fixing")`.
|
|
||||||
|
|
||||||
**Три вещи, на которых чертёж молча выходит неверным** — держи их в голове, детали в справочнике:
|
|
||||||
|
|
||||||
- `viewNumber=0` — это НЕ главный вид, а координаты ЛИСТА; знак, поставленный «на главном виде» с
|
|
||||||
нулём, уезжает за границы формата (`help(topic="drawing-views")`);
|
|
||||||
- ассоциативны только диаметральный и радиальный размеры; линейный и угловой меряют координаты, и
|
|
||||||
«60» останется, когда деталь станет 70 — после правки модели перепроверяй их сам
|
|
||||||
(`help(topic="drawing-dimensions")`);
|
|
||||||
- допуск, не легший в размер, виден только по пустому read-back в ответе — техтребования его не
|
|
||||||
заменят (`help(topic="drawing-dimension-text")`).
|
|
||||||
|
|
||||||
Ещё две ловушки, о которых узнаёшь только столкнувшись: штамп частично ведёт МОДЕЛЬ, а не чертёж
|
|
||||||
(`help(topic="drawing-title-block")`), и у цилиндрической грани нет «координат оси» — её
|
|
||||||
восстанавливают и проверяют сходимостью площадей (`help(topic="cylinder-axis")`).
|
|
||||||
|
|
||||||
**Чего нет.** Выносного элемента (увеличенный фрагмент), МЕСТНОГО разреза внутри вида, местного
|
|
||||||
вида и вида с разрывом. Ассоциативного ЛИНЕЙНОГО размера нет и не будет: в API у него нет привязки к геометрии
|
|
||||||
ни под каким именем (проверено QI, поздним связыванием и размером с обрывом). Экспорта в PDF/DXF
|
|
||||||
тоже нет — наружу уходит растр (`drawing_export_image`) и STEP.
|
|
||||||
|
|
||||||
## Работа с импортом / сборками
|
## Работа с импортом / сборками
|
||||||
|
|
||||||
Конвейер «импорт → разбор → извлечение детали → осмотр → модификация → экспорт»:
|
Конвейер «импорт → разбор → извлечение детали → осмотр → модификация → экспорт» для ЧУЖОЙ модели —
|
||||||
|
[reference/import-playbook.md](reference/import-playbook.md).
|
||||||
|
|
||||||
1. **`import_model`** — `type` задаёт документ: `assembly` (по умолчанию) или `part`.
|
## Исполнения: одна модель — несколько геометрий
|
||||||
Формат берётся из расширения; `.prt` и `.asm` носят несколько САПР сразу — там задавай `format`
|
|
||||||
явно. Нужна отдельная деталь файлом — включай `createComponentFiles`: без него импорт не пишет
|
Типоразмеры, зеркала, версии с отверстием и без в одном файле — переключение равно смене документа
|
||||||
на диск ничего, кроме открытого документа.
|
(хендлы гибнут), индексация и адресация в сборке, порядок «сначала геометрия, исполнения последним
|
||||||
Плоский чертёж (.dxf/.dwg) читает не он, а `import_drawing`.
|
шагом» — [reference/embodiments-playbook.md](reference/embodiments-playbook.md).
|
||||||
2. **Разбор:** `describe_model(sections=components)` (у каждого компонента — origin, поворот,
|
|
||||||
фиксация) и `describe_model(sections=mates)`, если сборка пришла со связями; грани компонента —
|
|
||||||
`list_faces(component=N)`. Извлечённую деталь открывай самостоятельным документом.
|
|
||||||
Гашение видимости компонента на снимок **не влияет** — изоляция так не делается.
|
|
||||||
3. **Осмотр — структурно** (`describe_model`: какая ось «высота», МЦХ, топология). Снимок
|
|
||||||
`model_snapshot(view=…)` — ракурс выбирай по плоскости детали (плоскую смотри сверху или
|
|
||||||
спереди, не в изометрии); один и тот же `view` даёт воспроизводимый кадр «до/после».
|
|
||||||
**Пары ракурсов противоположны по оси:** `front` смотрит из +Z, `rear` — из −Z, так же
|
|
||||||
`top`/`bottom` и `left`/`right`. Следствие, которое нужно чаще всего: деталь, лежащая на столе
|
|
||||||
гранью Z=0 (эскиз на XOY, выдавливание вперёд), видна столу как **`rear`**, а `front` покажет
|
|
||||||
зеркальную картинку. Читаемость надписи или логотипа доказывают снимком с нужной стороны, а не
|
|
||||||
рассуждением.
|
|
||||||
4. **Модификация «тупой» B-rep** (итог — в ответе каждой операции): простой случай — `move_face`;
|
|
||||||
вставка N мм в призматическую ножку — `split_solid_by_plane` → `move_body` → `move_face` (мост)
|
|
||||||
→ `boolean_union` (шаги пронумерованы в описаниях самих инструментов; цепочка проверена
|
|
||||||
end-to-end: проставка 39.45 → 41.45 мм, построение чистое).
|
|
||||||
5. **Перед выдачей:** последняя операция «Построение чистое» → `export_model` (STEP для обмена,
|
|
||||||
STL для печати).
|
|
||||||
|
|
||||||
## Эвристики и подводные камни
|
## Эвристики и подводные камни
|
||||||
|
|
||||||
@@ -503,6 +377,32 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
- **Направление операции** (`extrude(forward)`, знак `distance` у `move_face`): на выбранной грани
|
- **Направление операции** (`extrude(forward)`, знак `distance` у `move_face`): на выбранной грани
|
||||||
зависит от ориентации её нормали — реши ДО построения, прочитав нормаль в `list_faces(index=N)`
|
зависит от ориентации её нормали — реши ДО построения, прочитав нормаль в `list_faces(index=N)`
|
||||||
(или по снимку), а после сверь сводку объёма в ответе.
|
(или по снимку), а после сверь сводку объёма в ответе.
|
||||||
|
- **У ВЫРЕЗА `forward` смотрит в другую сторону, чем у прилива.** Замерено на плите Z 0..10 с
|
||||||
|
эскизом на плоскости z=10: `extrude(mode=boss, forward=true)` наращивает ВВЕРХ, а
|
||||||
|
`extrude(mode=cut, forward=true)` режет ВНИЗ, в тело. То есть у выреза «прямое» — это внутрь
|
||||||
|
материала. Оба умолчания делают то, чего обычно и хотят, но рассуждение «forward — это плюс
|
||||||
|
нормали» даст перевёрнутый карман. **Вырез, ушедший в пустоту, КОМПАС считает успехом** —
|
||||||
|
дерево чистое, объём не изменился; ловит это только строка сверки в ответе. Поэтому у
|
||||||
|
`extrude`/`revolve(mode=cut)` **не задавай `forward`, если сторона неочевидна**: сервер сам
|
||||||
|
переделает вырез, не убравший материала, в обратную сторону и скажет об этом в ответе.
|
||||||
|
Выбор работает, только если одна сторона пуста: эскиз ВНУТРИ материала (плоскость посреди вала)
|
||||||
|
режет в обе стороны — там `forward` задавай сам и сверяй объём.
|
||||||
|
- **На YOZ деталь растёт в МИНУС X, и туда же уезжает смещение плоскости.** Нормаль базовой
|
||||||
|
плоскости смотрит в плюс своей оси не всегда — замерено: XOY → +Z, XOZ → +Y, а **YOZ → −X**.
|
||||||
|
Значит `extrude(forward=true)` по эскизу на YOZ кладёт материал в отрицательные X, а
|
||||||
|
`sketch_create(plane="YOZ", offset=30)` ставит плоскость в X = −30, а не +30. Обе вещи следуют
|
||||||
|
одной нормали, так что путаницы между ними нет — но знак учитывай при компоновке, иначе деталь
|
||||||
|
уедет зеркально задуманному. Таблица целиком — `help(topic="build-verification")`.
|
||||||
|
- **`sketch_update` несущего эскиза МОЛЧА теряет часть отделки.** Фаска и скругление, снятые по
|
||||||
|
точкам, после переиздания базового контура остаются в дереве, ошибок не дают — а построены
|
||||||
|
оказываются не на всех рёбрах: замерено трижды на одной детали, из четырёх скруглений выживали
|
||||||
|
то два, то одно. Иногда КОМПАС всё же сознаётся («код 145: операция потеряла опорные объекты»),
|
||||||
|
но чаще молчит, и единственный признак — объём: он оказывается БОЛЬШЕ ожидаемого ровно на
|
||||||
|
недоснятый материал. Порядок после каждого переиздания несущего эскиза: сверить объём с прикидкой
|
||||||
|
либо пересчитать результат отделки (`list_faces(type="cylinder")` для скруглений — их должно быть
|
||||||
|
ровно столько, сколько рёбер в пакете); недосчитались — снести отделочные узлы
|
||||||
|
(`feature_delete(featureIndices=[…])`) и построить заново, уже по новым рёбрам. Пересборка
|
||||||
|
дешевле поиска виновного, а «построение чистое» здесь не значит ничего.
|
||||||
- **Эскизы и операции адресуются ХЕНДЛАМИ из ответов** — `sk_7c1e5aa3f1_1_2`, `op_7c1e5aa3f1_1_5`.
|
- **Эскизы и операции адресуются ХЕНДЛАМИ из ответов** — `sk_7c1e5aa3f1_1_2`, `op_7c1e5aa3f1_1_5`.
|
||||||
Не сочиняй их и не передавай числа: числовая адресация не поддерживается, а сервер объяснит формат
|
Не сочиняй их и не передавай числа: числовая адресация не поддерживается, а сервер объяснит формат
|
||||||
отказом. Хендл живёт только в текущей сессии построения: смена активного документа
|
отказом. Хендл живёт только в текущей сессии построения: смена активного документа
|
||||||
@@ -512,7 +412,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
Хендл — это НЕ индекс: `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`).
|
||||||
Если ответ вместо хендла говорит «выдать не удалось» — операция построена, но адресовать её
|
Если ответ вместо хендла говорит «выдать не удалось» — операция построена, но адресовать её
|
||||||
нечем: переставить её потом можно только пересборкой.
|
нечем: переставить её потом можно только пересборкой.
|
||||||
- **Единицы — мм** (геометрия) и **кг** (масса). Локальные координаты эскиза ≠ мировые координаты
|
- **Единицы — мм** (геометрия) и **кг** (масса). Локальные координаты эскиза ≠ мировые координаты
|
||||||
@@ -533,7 +433,7 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
сохранения.
|
сохранения.
|
||||||
|
|
||||||
- **Строишь параллельно с кем-то — `instance="private"`** при первом `kompas_connect` (потом режим
|
- **Строишь параллельно с кем-то — `instance="private"`** при первом `kompas_connect` (потом режим
|
||||||
не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_set_visible true`
|
не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_connect(visible=true)`
|
||||||
покажет).
|
покажет).
|
||||||
- **`shared` оставляй**, когда работа идёт на глазах у человека и ты единственный агент.
|
- **`shared` оставляй**, когда работа идёт на глазах у человека и ты единственный агент.
|
||||||
- **Один файл в двух экземплярах не открыть** — второй получит его только на чтение: работу делите
|
- **Один файл в двух экземплярах не открыть** — второй получит его только на чтение: работу делите
|
||||||
@@ -541,9 +441,12 @@ variables | errors | components` (`sections` сужает и ответ, и об
|
|||||||
|
|
||||||
## Открытые вопросы / границы
|
## Открытые вопросы / границы
|
||||||
|
|
||||||
- **Параметрика работает через параметры ОПЕРАЦИЙ, а не размеры эскиза** — сдвинуть контур
|
- **Координата в точке — число или выражение (считается один раз), а форму контура ведут `dimensions`** с выражениями
|
||||||
переменной нельзя, только пересобрать эскиз. Планируй членение так, чтобы изменяемое задавалось
|
(`help(topic="sketch-dimensions")`). Уже наложенный размер перепривязывается без пересборки:
|
||||||
параметром операции (глубина, радиус, габарит примитива), а не координатами в эскизе.
|
`link_parameter(feature=<узел эскиза>, parameter="v15")` — имя `vNN` есть в ответе
|
||||||
|
`sketch_create` и в `list_parameters` (у одноимённых «Линейный размер» — в скобках). Эскиз без
|
||||||
|
размеров переменной не двигается — только пересборкой (`sketch_update`); положение эскиза задаёт
|
||||||
|
**плоскость** — обычный узел с параметром «Расстояние».
|
||||||
- **2D покрыт вместе с разрезом и сечением.** Есть виды (с выбором набора, ориентации главного и
|
- **2D покрыт вместе с разрезом и сечением.** Есть виды (с выбором набора, ориентации главного и
|
||||||
невидимых линий), разрез/сечение, листы, штамп, размеры с допусками, осевые, обозначения,
|
невидимых линий), разрез/сечение, листы, штамп, размеры с допусками, осевые, обозначения,
|
||||||
техтребования, удаление и сдвиг объекта, вывод в растр — методика в §«Чертёж». Нет выносного
|
техтребования, удаление и сдвиг объекта, вывод в растр — методика в §«Чертёж». Нет выносного
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Сборка: собрать своё
|
||||||
|
|
||||||
|
Дополнение к SKILL.md — методика для сборки С НУЛЯ. Разбор ЧУЖОЙ сборки (пришедшей STEP/импортом) —
|
||||||
|
`reference/import-playbook.md`.
|
||||||
|
|
||||||
|
Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.**
|
||||||
|
|
||||||
|
1. **Детали сначала сохрани в файлы.** Компонент вставляется ссылкой на `.m3d`/`.a3d`, поэтому
|
||||||
|
несохранённую деталь вставить нельзя.
|
||||||
|
2. **`document_create assembly` → `assembly_add_component(filePath, x, y, z, rx, ry, rz)`.** Углы — в
|
||||||
|
градусах, вокруг СОБСТВЕННЫХ осей компонента и по очереди X→Y→Z: второй угол считается уже от
|
||||||
|
повёрнутого положения. Пока задан один угол, разницы с мировыми осями нет.
|
||||||
|
3. **Зафиксируй базовую деталь СРАЗУ: `assembly_fix_component(componentIndex=0, fixedState=true)`.** КОМПАС не закрепляет
|
||||||
|
никого сам, включая первый компонент, и решатель двигает того, кого сочтёт нужным — в том числе
|
||||||
|
основание, вокруг которого ты собираешь всё остальное. Это самая частая причина «сопряжение
|
||||||
|
верное, а сборка расползлась».
|
||||||
|
4. **Сопрягай:** `assembly_add_mate(mateType, …)` — семь типов, адресация гранью и смысл
|
||||||
|
`orientation` в `help(topic="assembly-mates")`. Что решаешь ты, а не справочник:
|
||||||
|
- **Грань адресуй индексом, а не координатами:** `list_faces(component=N)` → пара
|
||||||
|
`faceIndex`+`componentIndex`. Точки на бумаге считать не нужно, и сервер сам проверит, что
|
||||||
|
грань принадлежит этому компоненту.
|
||||||
|
- **Сторону зазора у `distance` задаёт ВЫБОР ПАРЫ ГРАНЕЙ, и от стартового положения она не
|
||||||
|
зависит.** «Closest» — не «ближайшее»: при сонаправленных нормалях объект 1 садится со стороны
|
||||||
|
−n относительно объекта 2 (замерено двойным прогоном). Практическое правило: бери пару граней,
|
||||||
|
которые смотрят ДРУГ НА ДРУГА. Вышло зеркально — меняй грань, а не `orientation`.
|
||||||
|
- **Первое сопряжение вешай на зафиксированную деталь.** Пока в цепочке нет ни одного
|
||||||
|
закреплённого звена, решатель волен двигать любое; связка «каждый новый компонент — к уже
|
||||||
|
стоящему на месте» разваливается вдвое реже, чем связка «все ко всем».
|
||||||
|
5. **`rebuild`,** если авто-валидация написала «ℹ Требуется перестроение». Это НЕ ошибка построения:
|
||||||
|
так помечает себя свежий компонент или только что наложенная связь. Бросать работу здесь не надо
|
||||||
|
— правило «не продолжай при ⚠» касается строки со знаком ⚠, а не этой.
|
||||||
|
**Исключение из правила «⚠ = стоп».** После КАЖДОГО сопряжения авто-валидация пишет
|
||||||
|
«⚠ N операц. в ошибке: „Сопряжения“ (код 0: ошибки нет)». Это то же «требуется перестроение»,
|
||||||
|
только под знаком ⚠: код 0 и имя операции «Сопряжения» означают, что ломаться нечему. Делай
|
||||||
|
`rebuild` и иди дальше. Настоящая беда со связью видна не здесь, а в
|
||||||
|
`describe_model(sections=mates)` — по пометке `valid:false`.
|
||||||
|
6. **Проверь:**
|
||||||
|
- `describe_model(sections=components)` — origin, поворот ЧИСЛАМИ (`rx/ry/rz` в градусах, та же
|
||||||
|
семантика, что у вставки) и «зафиксирован/свободен» у каждого: этим и видно, КОГО и НА СКОЛЬКО
|
||||||
|
подвинул решатель;
|
||||||
|
- `describe_model(sections=mates)` — что с чем связано, с каким значением и не выродилось ли.
|
||||||
|
Это ключевой детектор: `assembly_add_mate` может ответить успехом, а связь окажется
|
||||||
|
вырожденной;
|
||||||
|
- `measure(kind1=face, index1=…, componentIndex1=…, kind2=face, index2=…, componentIndex2=…)` —
|
||||||
|
зазор между деталями напрямую, без арифметики по габаритам;
|
||||||
|
- `assembly_check_interference(componentIndex1, componentIndex2)` — **не налезли ли детали друг
|
||||||
|
на друга.** Проверяй все пары, которые должны идти впритирку.
|
||||||
|
|
||||||
|
**Неудачную связь не нужно пересобирать с нуля:** `assembly_delete(target="mate"|"component", index)`
|
||||||
|
снимает сопряжение или компонент вместе с опирающимися на него связями. Индексы после удаления
|
||||||
|
сдвигаются — иди от больших к меньшим и перечитывай `describe_model(sections=mates)`.
|
||||||
|
|
||||||
|
**Пересечение деталей не видно НИГДЕ, кроме `assembly_check_interference`.** Сборка складывается из
|
||||||
|
готовых тел, и КОМПАС их не вычитает: две детали могут занимать общий объём, а сопряжения при этом
|
||||||
|
останутся `valid`, раздел `errors` — пустым, объём экспорта — простой суммой компонентов. `measure`
|
||||||
|
тоже не спасает: нулевой зазор одинаково означает и касание, и взаимопроникновение. Проверяй все
|
||||||
|
пары, которые должны идти впритирку.
|
||||||
|
|
||||||
|
**«Тела: 0» в сборке означает не «пусто», а «спрошено не то»:** тела принадлежат компонентам
|
||||||
|
(`describe_model(component=N, …)`), а `box` и `mass` без `component` честно дают габарит и МЦХ сборки
|
||||||
|
целиком. Про разные системы координат внутри паспорта компонента —
|
||||||
|
`help(topic="model-inspection")`; про локальные координаты граней и `pointOnFace` —
|
||||||
|
`help(topic="face-addressing")`.
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
# Чертёж: оформить деталь по ГОСТ
|
||||||
|
|
||||||
|
Дополнение к SKILL.md — методика оформления 2D-чертежа. Чертёж строится не так, как деталь:
|
||||||
|
**авто-валидации здесь нет**. Правило трёх проверок из SKILL.md §«Два правила прежде всего» в 2D не
|
||||||
|
работает — операция не отчитывается «построилось верно», потому что верность тут не про геометрию,
|
||||||
|
а про место на листе. Проверять приходится самому, и способ ровно один: посмотреть.
|
||||||
|
|
||||||
|
**Порядок, который окупается:**
|
||||||
|
|
||||||
|
1. **Деталь строится в чертёжной ориентации.** Набор видов задаётся ОТ модели: `mainOrientation`
|
||||||
|
выбирает, какую ориентацию модели показывает главный вид, но саму ориентацию модели он не
|
||||||
|
вращает. Если самая информативная проекция детали — не одна из шести стандартных, чертежа по
|
||||||
|
ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость
|
||||||
|
с наибольшей информацией.
|
||||||
|
2. **`drawing_set_sheet_format`** (формат до видов — иначе виды придётся двигать), при
|
||||||
|
необходимости `drawing_set_sheet_format(add=true)` для второго листа.
|
||||||
|
3. **`drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…)`** — бери ровно те
|
||||||
|
проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. **Главный вид
|
||||||
|
входит в набор сам**: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому `views=["top"]`
|
||||||
|
даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими.
|
||||||
|
4. **Координаты — замером, а не формулой.** `describe_drawing(sections=view, viewNumber)` отдаёт паспорт вида
|
||||||
|
одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает
|
||||||
|
начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось
|
||||||
|
проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид
|
||||||
|
арифметикой; отдельные точки переводит `drawing_project_point(x, y, z, viewNumber)`.
|
||||||
|
Выводить оси из головы не надо и вредно: у КОМПАС «спереди» показывает плоскость XY детали, а
|
||||||
|
«сверху» — X и **минус Z**, и **знаки инверсии зависят от `mainOrientation`** — формула,
|
||||||
|
выведенная на одном чертеже, на соседнем врёт.
|
||||||
|
5. **Разрез — до размеров, а не после.** Внутреннюю геометрию (зенковка, ступенчатое отверстие,
|
||||||
|
паз, глубокая расточка, полость) показывай разрезом, а не невидимыми линиями: по штриховой линии
|
||||||
|
нельзя ни поставить нормальный размер, ни разобрать форму. `drawing_add_section_view` — см.
|
||||||
|
§«Разрез» ниже. Размеры внутренней геометрии ставятся УЖЕ НА РАЗРЕЗЕ, поэтому строить его надо
|
||||||
|
раньше простановки, иначе размеры придётся переносить.
|
||||||
|
6. **Размеры**, `drawing_add_axis` (осевые и центровые), шероховатость, выноски, техтребования,
|
||||||
|
штамп. **Осевые сначала посмотри, потом добивай**: ассоциативные виды приходят со СВОИМИ
|
||||||
|
центровыми и осевыми, которые КОМПАС ставит сам, и `drawing_add_axis` вслепую даёт дубли поверх
|
||||||
|
существующих. Сначала `describe_drawing(kind="axis"|"centreMarker", viewNumber=…)`.
|
||||||
|
7. **`drawing_export_image`** — посмотреть глазами. Пока картинки не было, чертёж не сдан.
|
||||||
|
|
||||||
|
## Разрез
|
||||||
|
|
||||||
|
`drawing_add_section_view` делает всё сразу: проводит линию разреза на базовом виде и строит по ней
|
||||||
|
производный вид со штриховкой. Механика, ступенчатый разрез и встроенная проверка честности —
|
||||||
|
`help(topic="drawing-sections")`; здесь только решения, которые принимаешь ты:
|
||||||
|
|
||||||
|
- **Разрез или `hiddenLines`.** Разрез — когда внутреннее нужно ИЗМЕРИТЬ или показать форму:
|
||||||
|
зенковка и цековка, ступенчатое или резьбовое отверстие, паз, канавка, глубокая расточка, тонкая
|
||||||
|
стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к
|
||||||
|
штриховой линии не привязывают.
|
||||||
|
- **Веди линию с запасом за габарит** (плита 60 мм → от −40 до +40): линия по самому краю режет не
|
||||||
|
всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `describe_drawing(sections=view)`.
|
||||||
|
- **Строй разрез, когда модель готова**: после правки детали перестраивается только ПЕРВЫЙ разрез
|
||||||
|
базового вида. Модель всё же изменилась — снеси разрезы и построй заново.
|
||||||
|
- Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру.
|
||||||
|
|
||||||
|
**Промах простановки лечится, а не остаётся навсегда.** Отката (undo) у чертежа нет, но
|
||||||
|
`describe_drawing` показывает обозначения с индексами, `drawing_delete(target=object)` убирает одно, а
|
||||||
|
`drawing_move_object` его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не
|
||||||
|
заменой размера на выноску. Так же правится и компоновка: `drawing_move_view` переставляет вид со
|
||||||
|
всеми обозначениями, `drawing_create_standard_views(views=[])` доносит недостающую проекцию, `drawing_delete(target=view)` убирает
|
||||||
|
лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления —
|
||||||
|
`help(topic="drawing-fixing")`.
|
||||||
|
|
||||||
|
**Три вещи, на которых чертёж молча выходит неверным** — держи их в голове, детали в справочнике:
|
||||||
|
|
||||||
|
- `viewNumber=0` — это НЕ главный вид, а координаты ЛИСТА; знак, поставленный «на главном виде» с
|
||||||
|
нулём, уезжает за границы формата (`help(topic="drawing-views")`);
|
||||||
|
- ассоциативны только диаметральный и радиальный размеры; линейный и угловой меряют координаты, и
|
||||||
|
«60» останется, когда деталь станет 70 — после правки модели перепроверяй их сам
|
||||||
|
(`help(topic="drawing-dimensions")`);
|
||||||
|
- допуск, не легший в размер, виден только по пустому read-back в ответе — техтребования его не
|
||||||
|
заменят (`help(topic="drawing-dimension-text")`).
|
||||||
|
|
||||||
|
Ещё две ловушки, о которых узнаёшь только столкнувшись: штамп частично ведёт МОДЕЛЬ, а не чертёж
|
||||||
|
(`help(topic="drawing-title-block")`), и у цилиндрической грани нет «координат оси» — её
|
||||||
|
восстанавливают и проверяют сходимостью площадей (`help(topic="cylinder-axis")`).
|
||||||
|
|
||||||
|
**Чего нет.** Выносного элемента (увеличенный фрагмент), МЕСТНОГО разреза внутри вида, местного
|
||||||
|
вида и вида с разрывом. Ассоциативного ЛИНЕЙНОГО размера нет и не будет: в API у него нет привязки к геометрии
|
||||||
|
ни под каким именем (проверено QI, поздним связыванием и размером с обрывом). Экспорта в PDF/DXF
|
||||||
|
тоже нет — наружу уходит растр (`drawing_export_image`) и STEP.
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Исполнения: одна модель — несколько геометрий
|
||||||
|
|
||||||
|
Дополнение к SKILL.md. Типоразмеры (профиль на 100, 200, 500 мм), правое и левое зеркало, версии с
|
||||||
|
отверстием и без часто живут **в одном файле** исполнениями. Тогда всё, что ты меришь и
|
||||||
|
экспортируешь, относится к **текущему** исполнению — не к «детали вообще».
|
||||||
|
|
||||||
|
- **Признак замечаешь не ты, а ответ.** У модели с несколькими исполнениями `describe_model` сам
|
||||||
|
пишет, сколько их и какое сейчас текущее. Увидел эту строку — прежде чем считать массу или резать
|
||||||
|
чертёж, посмотри `describe_model(sections=embodiments)`: там габарит и масса **каждого**, и это
|
||||||
|
чтение ничего не переключает.
|
||||||
|
- **Переключение равно смене документа.** `embodiment(action="set", target="L200")` обнуляет
|
||||||
|
сессию построения: хендлы `sk_…`/`op_…` после него мертвы. Сохраняй документ до переключения.
|
||||||
|
- **Индекс живёт до первой правки дерева**: после `delete` индексы смещаются. Адресуй обозначением
|
||||||
|
(«L500»), а индексом — только сразу после того, как увидел список. У **варианта** обозначение
|
||||||
|
родительское, и адресовать его номером нельзя вовсе — под «-01» подходят двое; зови его по имени
|
||||||
|
(«M5-01») или индексом.
|
||||||
|
- **Исполнения делай ПОСЛЕДНИМ шагом.** Переключение убивает хендлы, и дальнейшая правка дерева
|
||||||
|
идёт уже через `feature_delete(featureIndex=…)` по `describe_model(sections=tree)` — путь рабочий,
|
||||||
|
но менее удобный. Сначала доведи базовую геометрию и параметризацию, потом размножай.
|
||||||
|
- **Строишь новое исполнение** — `embodiment(action="add", number="02")`; оно сразу становится
|
||||||
|
текущим, строй в нём немедленно. `depended=false` нужен, когда правки НЕ должны наследоваться от
|
||||||
|
родителя, — иначе изменение уедет и в него.
|
||||||
|
- **В сборку исполнение выбирается явно**: `assembly_add_component(embodiment="L500")`. Без
|
||||||
|
параметра встанет **базовое** исполнение, а не то, что сохранено в файле текущим. Обозначение
|
||||||
|
нужно ПОЛНОЕ («ПРОБА.001-01», а не «-01»); сервер откажет, если КОМПАС подсунет базовое.
|
||||||
|
- **«Удлинить эти профили с 500 до 600» — это смена исполнения экземпляра, а не новая вставка**:
|
||||||
|
`embodiment(action="set", target="L600", component=N)` и затем `rebuild`. Сопряжения при этом
|
||||||
|
**сохраняются** — пересоздание вставки, наоборот, порвало бы их все. Какие исполнения есть у
|
||||||
|
конкретного экземпляра, показывает `describe_model(sections="embodiments", component=N)`.
|
||||||
|
- **Исполнения, отличающиеся одним размером, — это переменная, а не правка дерева.** Значение
|
||||||
|
переменной каждое исполнение (и вариант) хранит СВОЁ: `set_variable` после `embodiment(add)`
|
||||||
|
меняет только текущее, у наследников выражение становится ссылкой на родителя
|
||||||
|
(`VCM.001|fit_h`). Отсюда приём: построй базу на переменных, затем `add` → `set_variable` в
|
||||||
|
каждом исполнении. Убрать элемент в исполнении часто проще значением, чем `feature_delete`:
|
||||||
|
цековка с `cb_d = hole_d` уходит в уже вырезанное.
|
||||||
|
- **Выгнать всю линейку на печать** — `export_model(embodiment="all")`: каждое исполнение в свой
|
||||||
|
файл с суффиксом обозначения.
|
||||||
|
- **После смены исполнения в собранном узле проверь сопряжения** (`sections="mates"`): если у нового
|
||||||
|
исполнения нет объекта, на который опиралась связь, она рвётся — «ССЫЛКА ПОТЕРЯНА», `valid: false`,
|
||||||
|
компонент недоопределён. Что было потеряно, хранит имя сопряжения; `assembly_delete` сотрёт и его.
|
||||||
|
|
||||||
|
Подробности и границы — `help(topic="embodiments")`.
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Фрагмент — переиспользуемый чертёж, а не сечение
|
||||||
|
|
||||||
|
Дополнение к SKILL.md. Эскиз живёт внутри дерева построения и вне его не существует; фрагмент (*.frw)
|
||||||
|
— самостоятельный файл, который переживает деталь. `fragment_create` его пишет, `fragment_place`
|
||||||
|
кладёт в активный чертёж или другой фрагмент, а `mode` решает, чем он там станет — и это разные
|
||||||
|
объекты, а не оттенки одного:
|
||||||
|
|
||||||
|
- **`reference`** — вставка-ссылка: содержимым владеет файл, правка файла меняет все документы, куда
|
||||||
|
он вставлен. Ради этого фрагменты и заводят: одна заготовка на десять чертежей.
|
||||||
|
- **`copy`** — копия внутри документа, живёт своей жизнью; файл потом можно удалить.
|
||||||
|
- **`local`** — вставка, переиспользуемая только внутри этого документа.
|
||||||
|
- **`explode`** — россыпь обычных примитивов: правится по одному, но связи с файлом уже нет.
|
||||||
|
|
||||||
|
**Имя вставки общее у вставок одного файла одного вида.** Вторая копия того же файла получает имя
|
||||||
|
первой, и `name` второго вызова не применяется. Ответ `fragment_place` называет фактическое имя
|
||||||
|
и прямо говорит, если запрошенное не легло. Нужны разные имена — кладите разные файлы.
|
||||||
|
|
||||||
|
`angle` (градусы), `scale` и `mirror` задают размещение; зеркалить можно только вставку — у россыпи
|
||||||
|
отражать нечего. **Зеркало отражает относительно вертикали через точку вставки**, поэтому контур
|
||||||
|
уходит в другую сторону от неё: вставка в x=220 после `mirror` занимает 160…220, а не 220…280.
|
||||||
|
|
||||||
|
Проверять результат — `describe_drawing`: он показывает состав по типам, габарит и все вставки
|
||||||
|
с их файлами. Вставка, чей файл потерялся, рисуется пустым местом — в списке она помечена
|
||||||
|
недействительной, и это единственный способ отличить её от удавшейся, не глядя на экран.
|
||||||
|
|
||||||
|
Контур, который переживёт конкретную деталь (логотип, шаблон, профиль), клади во фрагмент —
|
||||||
|
`fragment_create(path, entities)` тем же списком примитивов. Активный документ он не подменяет,
|
||||||
|
поэтому фрагмент можно снять посреди построения детали; габарит в ответе снят с самого документа —
|
||||||
|
сверяй его с задуманным.
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# Работа с импортом / сборками
|
||||||
|
|
||||||
|
Дополнение к SKILL.md — конвейер разбора ЧУЖОЙ модели/сборки: «импорт → разбор → извлечение детали →
|
||||||
|
осмотр → модификация → экспорт». Сборка С НУЛЯ — `reference/assembly-playbook.md`.
|
||||||
|
|
||||||
|
1. **`import_model`** — `type` задаёт документ: `assembly` (по умолчанию) или `part`.
|
||||||
|
Формат берётся из расширения; `.prt` и `.asm` носят несколько САПР сразу — там задавай `format`
|
||||||
|
явно. Нужна отдельная деталь файлом — включай `createComponentFiles` (по умолчанию `false`).
|
||||||
|
**Выключенный переключатель чистого диска НЕ гарантирует:** конвертер пишет файлы рядом с
|
||||||
|
ИСХОДНИКОМ и помимо него — замерено, четыре импорта положили четыре незапрошенных `.m3d`.
|
||||||
|
Что реально изменилось в каталоге исходника, ответ перечисляет поимённо; не хочешь засорять
|
||||||
|
чужой каталог — копируй файл во временный (`help(topic="model-exchange")`).
|
||||||
|
**STL/OBJ приходят СЕТКОЙ:** «тел 0, объём 0.0 мм³» после такого импорта — норма, а не провал,
|
||||||
|
проверяй габаритом; ответ говорит это вслух и называет число треугольников из самого файла.
|
||||||
|
Плоский чертёж (.dxf/.dwg) читает не он, а `import_drawing`.
|
||||||
|
2. **Разбор:** `describe_model(sections=components)` (у каждого компонента — origin, поворот,
|
||||||
|
фиксация) и `describe_model(sections=mates)`, если сборка пришла со связями; грани компонента —
|
||||||
|
`list_faces(component=N)`. Извлечённую деталь открывай самостоятельным документом.
|
||||||
|
Гашение видимости компонента на снимок **не влияет** — изоляция так не делается.
|
||||||
|
3. **Осмотр — структурно** (`describe_model`: какая ось «высота», МЦХ, топология). Снимок
|
||||||
|
`model_snapshot(view=…)` — ракурс выбирай по плоскости детали (плоскую смотри сверху или
|
||||||
|
спереди, не в изометрии); один и тот же `view` даёт воспроизводимый кадр «до/после».
|
||||||
|
**Пары ракурсов противоположны по оси:** `front` смотрит из +Z, `rear` — из −Z, так же
|
||||||
|
`top`/`bottom` и `left`/`right`. Следствие, которое нужно чаще всего: деталь, лежащая на столе
|
||||||
|
гранью Z=0 (эскиз на XOY, выдавливание вперёд), видна столу как **`rear`**, а `front` покажет
|
||||||
|
зеркальную картинку. Читаемость надписи или логотипа доказывают снимком с нужной стороны, а не
|
||||||
|
рассуждением.
|
||||||
|
**Но «ортогонально» — правило про ПЛОСКУЮ деталь.** Как только форма выходит из одной плоскости
|
||||||
|
(кронштейн, косынка, изогнутый профиль), ортогональный кадр перестаёт читаться: он плоский,
|
||||||
|
подписей осей на нём нет, и сопоставить увиденное с координатами не выходит — `right` даёт
|
||||||
|
картинку, по которой не сказать, где перёд. Профиль такой детали смотри `view="iso"`: там видно,
|
||||||
|
что куда загнуто.
|
||||||
|
4. **Модификация «тупой» B-rep** (итог — в ответе каждой операции). Инструмент выбирается по тому,
|
||||||
|
ЧТО задано в требовании, а не по тому, что привычнее:
|
||||||
|
|
||||||
|
| Требование звучит как | Инструмент | Почему не `move_face` |
|
||||||
|
|---|---|---|
|
||||||
|
| «сдвинуть грань на N мм» | `move_face` | это он и есть |
|
||||||
|
| «диаметр отверстия (бобышки) должен стать D» | **`resize_face`** | задаётся ДИАМЕТР, ось не двигается; `move_face` сдвинул бы стенку на (D−d)/2, и это пришлось бы считать самому |
|
||||||
|
| «грань должна встать НА объект: на плоскость, на грань соседнего тела» | **`replace_face`** | расстояние считает КОМПАС; `move_face` требует вычислить его заранее |
|
||||||
|
| вставка N мм в призматическую ножку | `split_solid_by_plane` → `move_body` → `move_face` (мост) → `boolean` | цепочка проверена end-to-end: проставка 39.45 → 41.45 мм |
|
||||||
|
|
||||||
|
`resize_face` и `replace_face` требуют КОМПАС v25; на версиях старше они отвечают отказом с
|
||||||
|
номером установленной версии, и тогда остаётся `move_face` с арифметикой.
|
||||||
|
|
||||||
|
**Проверяйте прямое редактирование РАЗНОСТЬЮ ОБЪЁМОВ против аналитической формулы** — объём и так
|
||||||
|
печатается в сводке каждой операции, лишних вызовов не нужно. Расточка отверстия обязана снять
|
||||||
|
ровно `π(R²−r²)·h`, наращивание грани — добавить ровно `площадь_грани × Δh`. Считайте формулу по
|
||||||
|
СВОИМ числам и сверяйте с тем, что напечатала операция: одно число ловит и «операция ушла не
|
||||||
|
туда», и «отверстие перестало быть сквозным».
|
||||||
|
|
||||||
|
**Оси отверстий сверяют полем `axis`.** У грани типа `cylinder`, `cone`, `torus` `list_faces`
|
||||||
|
отдаёт `axis` — точку на оси и направление, в мировых координатах; у цилиндра и сферы там же
|
||||||
|
`radius`. Требование «оси сдвигать нельзя» доказывается сравнением `axis` до и после, а не
|
||||||
|
арифметикой по расстояниям. Осторожно с двумя соседними полями: `normal` у цилиндра — про
|
||||||
|
сторону поверхности, а не про ось, а `pointOnFace` лежит на стенке (help(topic="cylinder-axis")).
|
||||||
|
5. **Перед выдачей:** последняя операция «Построение чистое» → `export_model` (STEP для обмена,
|
||||||
|
STL для печати).
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# Параметризация: сначала переменные, потом геометрия
|
||||||
|
|
||||||
|
Дополнение к SKILL.md §«Параметризация». Читай это перед первым эскизом нового документа — план
|
||||||
|
переменными стоит один вызов на размер, пока деталь пуста, и пересборку после десятка операций.
|
||||||
|
|
||||||
|
**В новом документе первым делом опиши будущую модель переменными — до первого эскиза.** Набор
|
||||||
|
переменных — это план построения числами и паспорт, по которому человек поймёт модель, не разбирая
|
||||||
|
дерево.
|
||||||
|
|
||||||
|
- **Заводи переменной то, что было РЕШЕНИЕМ**: габариты из ТЗ, толщины, зазоры, отступы, кегли,
|
||||||
|
радиусы. Выводимое задавай формулой (`plate_L = badge_L - 2*edge_gap`) — правка ведущего размера
|
||||||
|
пересчитает зависимые сама. Позиции, подобранные замером, оставляй числами: связь — обещание,
|
||||||
|
что правка переменной даст осмысленный результат, а на позиционных числах она чаще ломает деталь.
|
||||||
|
- **Размер передавай выражением прямо в операцию** (`extrude(depth="badge_T")`) — параметр сразу
|
||||||
|
становится ведомым, внутреннее имя параметра («Расстояние 1») знать не нужно. Переменная должна
|
||||||
|
существовать ДО операции — потому паспорт и заводят первым. Задним числом и для параметров,
|
||||||
|
которых нет среди аргументов инструмента (углы уклона, второе направление), — `link_parameter`.
|
||||||
|
- **Размер КОНТУРА — тоже выражением**, но не в координатах, а в `dimensions` у
|
||||||
|
`sketch_create`/`sketch_update`: ширина, длина отрезка, Ø/R, а с `to` — расстояние между точками
|
||||||
|
(шаг отверстий, отступ от края) и угол между отрезками. Координаты достаточно нарисовать
|
||||||
|
примерно — контур встанет по значению сразу.
|
||||||
|
- **Эскиз определён полностью, только когда привязан к модели.** Форма — размерами, положение —
|
||||||
|
от начала координат и осей: `to:{ref:"origin"}` (расстояние от базовых плоскостей, угол или
|
||||||
|
центр в начало через `coincident`), `coincident` с `ref:"xAxis"|"yAxis"` (точка на оси),
|
||||||
|
`symmetric` с `axis` (деталь симметрична оси — ширина растёт в обе стороны). Порядок для
|
||||||
|
каждого эскиза: **(1) где он стоит** — привязка к началу координат/осям; **(2) форма** — все
|
||||||
|
длины, радиусы, углы; **(3) взаимное положение** элементов — от привязанного контура или от
|
||||||
|
оси. Симметричную деталь строй симметрично оси модели: тогда её плоскости симметрии совпадают с
|
||||||
|
базовыми, и следующие эскизы привязываются к тем же осям. Нужна симметрия на уровне грани —
|
||||||
|
ставь эскиз не на грань, а на базовую плоскость со смещением (`offset`): у грани осей модели нет.
|
||||||
|
- **Читай хвост ответа.** «полностью определён» без строки «Закреплено там, где нарисовано» —
|
||||||
|
цель. Строка «Закреплено…» значит, что положение держит закреплённая сервером точка, а не
|
||||||
|
привязка: добавь `ref`. «⚠ НЕДООПРЕДЕЛЁН» — часть контура свободна и сдвинется при смене
|
||||||
|
переменной: допиши размер (чаще всего радиус дуги, угол наклонного отрезка или вторую ось
|
||||||
|
положения). Отказ «размер ЛИШНИЙ» — величина уже следует из других (касание, сшивка, симметрия)
|
||||||
|
— убери один. Поля, правила опоры и пример VESA — `help(topic="sketch-dimensions")`.
|
||||||
|
- **Промахи сервер ловит сам:** ссылка на несуществующее имя — отказ с перечнем виновных (и в
|
||||||
|
выражениях операций, и в `set_variable`), функции в формулах — предупреждение
|
||||||
|
(тригонометрия в радианах, разделитель аргументов «;», непонятая запись = молчаливый 0).
|
||||||
|
Имена: в ФОРМУЛЕ регистр значим (`aq` не найдёт `Aq`), а две переменные, различающиеся только
|
||||||
|
регистром, не уживаются — `spl_d` перезапишет `spl_D`. Константы π нет: заведи `dg =
|
||||||
|
0.017453292519943295` (градус в радианах) и пиши `sin(a*dg)`.
|
||||||
|
- **Связь — ограничением, а не арифметикой.** Центр дуги на окружности — `coincident` с
|
||||||
|
`to.point: "curve"`; опора вне профиля (основная окружность, ось паза) — примитив с
|
||||||
|
`construction: true`; сторона «в 3.5 от оси под 22.5°» — `distance` до `origin` плюс `angle` к
|
||||||
|
оси. Так связь живёт в эскизе и переживает смену переменной; посчитанные числа — нет.
|
||||||
|
- **Считает КОМПАС, а не ты:** связь — ограничением в эскизе, скругление — примитивом `fillet`,
|
||||||
|
точная начальная координата — выражением прямо в точке (`{"x": "rb*sin(phi*dg)"}`). Заводить
|
||||||
|
переменные-калькуляторы и переносить их значения в JSON не нужно. Твоя часть — **сверить
|
||||||
|
результат с прикидкой** (`sketch_describe`).
|
||||||
|
- **`note` обязателен** и пишется по-русски, со смыслом и единицей; `(ТЗ)` в тексте по-прежнему
|
||||||
|
полезен человеку, но для машины число из ТЗ метится ПРИЗНАКОМ:
|
||||||
|
`set_variable([{name:"dish_r", expression:"90", note:"по ТЗ", information:true}])`. Комментарий
|
||||||
|
вычистка не читает, признак — читает. **Что замерил — верни в переменную** (фактический кегль,
|
||||||
|
прирост каймы), иначе паспорт разойдётся с моделью и станет дезинформацией. Переосмысливать можно
|
||||||
|
всё, кроме помеченного `(ТЗ)`.
|
||||||
|
- **После связывания правка паспорта перестраивает деталь** (проверено: `set_variable(badge_T=4)` →
|
||||||
|
габарит по Z 3.00 → 4.00, объём 5154.5 → 5861.5 мм³). Это и есть параметрическая модель,
|
||||||
|
а не комментарий к ней. **До связывания — не перестраивает**, и `set_variable` говорит об этом
|
||||||
|
прямо: «⚠ НИЧЕГО НЕ ВЕДЁТ». Такой ответ — не успех: число поменялось, деталь нет. Исключение одно —
|
||||||
|
переменная и не должна ничего вести (справка из ТЗ): пометь её `information=true`, и пометка уйдёт
|
||||||
|
вместе с риском вычистки.
|
||||||
|
- **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт» — это либо забытая
|
||||||
|
связь, либо справка, которую забыли пометить, либо мусор; разбери все три.
|
||||||
|
`delete_variable(unused=true)` не трогает справочные (`information`) и внешние (`external`) —
|
||||||
|
остальное сносит без разбора. Значит порядок такой: `link_parameter` на всё, что должно вести
|
||||||
|
геометрию, `set_variable(information=true)` на всё, что остаётся справкой, и только потом уборка.
|
||||||
@@ -1,10 +1,65 @@
|
|||||||
# Надписи и рельеф — точная подгонка и отделка
|
# Надписи и рельеф — точная подгонка и отделка
|
||||||
|
|
||||||
Дополнение к разделу «Надписи, логотипы и рельеф» SKILL.md. Здесь — замеры и приёмы для точной
|
Дополнение к разделу «Надписи, логотипы и рельеф» SKILL.md: выбор маршрута для внешнего контура,
|
||||||
компоновки надписи (подгонка кегля и ширины, поведение каймы, стыковка блоков) и отделки рельефа.
|
перевод SVG-логотипа в примитивы эскиза, точная подгонка надписи (кегль, ширина, кайма, стыковка
|
||||||
Все числа получены пробами на конкретных начертаниях (Lobster, Bevan, Zilla Slab): это порядок
|
блоков) и отделка рельефа. Все числа получены пробами на конкретных начертаниях (Lobster, Bevan,
|
||||||
величины и форма зависимости, а не константы — свои значения перезамеряй на своём шрифте,
|
Zilla Slab): это порядок величины и форма зависимости, а не константы — свои значения перезамеряй
|
||||||
`widthFactor` и `thinThickness`.
|
на своём шрифте, `widthFactor` и `thinThickness`.
|
||||||
|
|
||||||
|
## Внешний контур: не диктуй координаты, если фигуру нельзя описать формулой
|
||||||
|
|
||||||
|
Три маршрута, и выбор между ними механический — не по вкусу, а по происхождению геометрии.
|
||||||
|
|
||||||
|
| Откуда фигура | Чем строить |
|
||||||
|
|---|---|
|
||||||
|
| **Вычисляется**: пластины, рёбра, сетка отверстий | `sketch_create(entities[])` — прямо в вызове, размеры вяжи переменными |
|
||||||
|
| **Срисована**: логотип, шаблон, кулачок, профиль | внешний вектор → JSON → `sketch_create(entitiesFile=…)` |
|
||||||
|
| **Пришла в CAD-формате**: файл от смежника | `import_drawing` (.dxf/.dwg) → фрагмент → `fragment_place` |
|
||||||
|
|
||||||
|
**Обводка занимает сотни примитивов, и переписывать их в тело вызова незачем.** У `sketch_create`,
|
||||||
|
`sketch_update(mode=append)` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`;
|
||||||
|
сервер читает файл сам. Замер на эмблеме Volvo: SVG в 1.5 КБ даёт 96 примитивов (50 отрезков +
|
||||||
|
46 дуг) и 9.5 КБ JSON; через `entitiesFile` это один вызов на одну строку аргументов, а эскиз
|
||||||
|
строится за один заход. Оба параметра можно задать вместе — сначала `entities`, следом файл:
|
||||||
|
так к готовому контуру дописывают рамку или ось, не трогая файл.
|
||||||
|
|
||||||
|
Что проверить **до** постройки, а не после: габарит в ответе (`fragment_create` печатает
|
||||||
|
фактический — сверь с задуманным) и вложенные контуры. Правил заливки у эскиза КОМПАС нет: любой
|
||||||
|
вложенный контур он режет как отверстие, даже там, где вектор заливал материал. Конвертер такие
|
||||||
|
места называет заранее — на них смотри до выдавливания, иначе дыры обнаружатся на снимке.
|
||||||
|
|
||||||
|
## Логотип, которого нет в шрифте: SVG → примитивы эскиза
|
||||||
|
|
||||||
|
Переводи готовый вектор в примитивы эскиза сам — `line` и `arc3points`, а не ломаной: контур из
|
||||||
|
сотен звеньев даёт деталь в сотни граней, и фаска по такому низу не строится. Кубические Безье режь
|
||||||
|
пополам, пока дуга по трём точкам не ляжет в допуск. Четыре вещи, каждая из которых стоила захода:
|
||||||
|
|
||||||
|
- **Ось Y в SVG смотрит вниз** — без инверсии контур встаёт вверх ногами, и это видно только на снимке.
|
||||||
|
- **Дуги задавай тремя точками** (`arc3points`): концы заданы явно, соседние примитивы стыкуются
|
||||||
|
точно. Перед постройкой проверь цепочку — конец примитива против начала следующего, разрыв 0.
|
||||||
|
- **Чисти мелочь под масштаб детали — параметром `minSegment`.** SVG рисуют в своём габарите (сотня
|
||||||
|
условных единиц), и его скругления после масштабирования превращаются в дуги по 0.02–0.5 мм;
|
||||||
|
замыкающий `z` часто даёт ещё и сегмент нулевой длины. `chamfer_edge` по такому набору отвечает
|
||||||
|
«катет больше длины N из M рёбер» — и это правда. Передай `sketch_create(minSegment=катет)` (тот же
|
||||||
|
параметр есть у `sketch_update` и `fragment_create`), и та же фаска пройдёт с первой попытки;
|
||||||
|
отчёт о выброшенном читай, а не пролистывай — `help(topic="contour-cleanup")`.
|
||||||
|
|
||||||
|
**Порядок для фаски по контуру логотипа — только такой, и он неочевиден:**
|
||||||
|
|
||||||
|
1. **чистка** порогом ≈ будущего катета (`minSegment`);
|
||||||
|
2. **замер ЧИЩЕНОГО силуэта** — `sketch_measure_thickness(entitiesFile, minSegment=тот же порог)`;
|
||||||
|
3. **катет по узкому месту** чищеного силуэта: `c ≤ (узкое_место − 2·w)/2`, где `w` — ширина нити.
|
||||||
|
|
||||||
|
Менять шаги местами нельзя: **чистка СУЖАЕТ узкое место**. Она заменяет скругление острым углом —
|
||||||
|
в выпуклом углу это добавляет материал (габарит подрастает), а в вогнутом срезает его, и именно
|
||||||
|
вогнутые углы образуют перемычки между штрихами. Сужение доходит до единиц процентов узкого места —
|
||||||
|
этого хватает, чтобы катет, подобранный по нечищеному контуру, перестал проходить свой же критерий.
|
||||||
|
Числа снимай на СВОЁМ контуре: они принадлежат рисунку, а не приёму.
|
||||||
|
|
||||||
|
- **Ширину штриха и узкое место меряй инструментом, а не глазом** — `sketch_measure_thickness`
|
||||||
|
ничего не строит и документа не требует, поэтому зовётся ДО эскиза
|
||||||
|
(`help(topic="silhouette-thickness")`). От этих чисел зависит, останется ли что-то от рисунка
|
||||||
|
после фаски и напечатается ли он вообще; шаг растра в ответе — точность округления катета.
|
||||||
|
|
||||||
## Подгонка ширины и кегля
|
## Подгонка ширины и кегля
|
||||||
|
|
||||||
@@ -61,7 +116,11 @@
|
|||||||
- **Толщина каймы — ещё и параметр стыковки блоков.** Кайма опускает силуэт надписи ниже её
|
- **Толщина каймы — ещё и параметр стыковки блоков.** Кайма опускает силуэт надписи ниже её
|
||||||
глифов на `t`, и именно это перекрытие с плашкой держит деталь одним телом. Считай так: низ
|
глифов на `t`, и именно это перекрытие с плашкой держит деталь одним телом. Считай так: низ
|
||||||
каймы = низ глифов − t, и он должен зайти на плашку хотя бы на несколько десятых. Проверка —
|
каймы = низ глифов − t, и он должен зайти на плашку хотя бы на несколько десятых. Проверка —
|
||||||
сводка «Тел:» в ответе самого `primitive(union)`.
|
сводка «Тел:» в ответе самого `primitive(union)`: у примитивов она надёжна, потому что сервер
|
||||||
|
сам сверяет объём до и после и отвергает объединение, ничего не давшее. **У `loft`/`sweep` этой
|
||||||
|
сводке верить нельзя** — там она однажды напечатала «Тел: 1», когда тел было два (см. основной
|
||||||
|
навык, п. «Ответ мутирующей операции»); в сомнительном случае считай тела
|
||||||
|
`describe_model(sections="bodies")`.
|
||||||
- **Кайма вокруг ПРЯМОУГОЛЬНОЙ плашки — вторым примитивом, а не тонкой стенкой.** Стенка обходит
|
- **Кайма вокруг ПРЯМОУГОЛЬНОЙ плашки — вторым примитивом, а не тонкой стенкой.** Стенка обходит
|
||||||
контуры эскиза, а плашка по playbook'у строится `primitive`, и каймы у неё не появится. Клади под
|
контуры эскиза, а плашка по playbook'у строится `primitive`, и каймы у неё не появится. Клади под
|
||||||
неё второй блок на `2·t` больше и на высоту подложки (85 × 13.5 × 2 под плашкой 82 × 10.5 × 3) —
|
неё второй блок на `2·t` больше и на высоту подложки (85 × 13.5 × 2 под плашкой 82 × 10.5 × 3) —
|
||||||
@@ -89,16 +148,15 @@
|
|||||||
до нужной части силуэта помогает `minY`/`maxY`). **Порядок «сначала скругления углов, потом фаска»
|
до нужной части силуэта помогает `minY`/`maxY`). **Порядок «сначала скругления углов, потом фаска»
|
||||||
работает** — дуги от R0.5 фаске не мешают. В отборе встречается тип `other` (у сложных кривых) —
|
работает** — дуги от R0.5 фаске не мешают. В отборе встречается тип `other` (у сложных кривых) —
|
||||||
он тоже принимается параметром `type`.
|
он тоже принимается параметром `type`.
|
||||||
- **Отказ фаски на НЕЧИЩЕНОМ контуре — не повод уменьшать катет: попробуй УВЕЛИЧИТЬ.** Успех
|
- **Отказ фаски на НЕЧИЩЕНОМ контуре — не повод уменьшать катет: успех немонотонен по размеру.**
|
||||||
немонотонен по размеру. На контуре логотипа (54 ребра низа, острые клинья между элементами)
|
На контуре с острыми клиньями между элементами `chamfer_edge` отказывает на нескольких катетах
|
||||||
`chamfer_edge` отказывает при 0.4, 0.5, 0.6 и 0.7 и проходит при **0.8** — проверено подряд,
|
подряд и проходит на большем — проверено подряд, с `rebuild` между попытками и на неизменных
|
||||||
с `rebuild` между попытками и на неизменных индексах рёбер. Похоже, малый катет оставляет в остром
|
индексах рёбер. Похоже, малый катет оставляет в остром клине вырожденный «нос», который КОМПАС
|
||||||
клине вырожденный «нос», который КОМПАС сшить не может, а большой срезает остриё целиком.
|
сшить не может, а большой срезает остриё целиком. **Но перебирать катет не надо**: правильное
|
||||||
**Но это верно ТОЛЬКО пока контур не почищен**, и полагаться на такой подбор не нужно: правильное
|
лечение — `minSegment` (см. SKILL.md §«Надписи, логотипы и рельеф»). После чистки совет «попробуй
|
||||||
лечение — `minSegment` (см. SKILL.md §«Надписи, логотипы и рельеф»), а не перебор катета.
|
увеличить» становится вреден: рабочий диапазон катета сдвигается ВНИЗ вместе с узким местом, и
|
||||||
Замер на том же логотипе: почищенный порогом 0.5 контур (34 примитива) фаску **0.5 принимает**,
|
катет, проходивший на нечищеном контуре, чищеный отвергает. Не переносите подобранное значение
|
||||||
а эталонные **0.8 отвергает** — рабочий диапазон катета сдвигается ВНИЗ вместе с узким местом
|
между состояниями контура — оно к ним привязано.
|
||||||
(1.98 → 1.82 мм). После чистки совет «попробуй увеличить» уже вреден.
|
|
||||||
Прежняя формулировка добавляла «исключение самых коротких рёбер картину не меняет, то есть дело
|
Прежняя формулировка добавляла «исключение самых коротких рёбер картину не меняет, то есть дело
|
||||||
не в них» — вывод неверен: исключённое из `edgeIndices` ребро остаётся в теле, и это не то же
|
не в них» — вывод неверен: исключённое из `edgeIndices` ребро остаётся в теле, и это не то же
|
||||||
самое, что убрать сегмент из контура. Убранный из контура — меняет.
|
самое, что убрать сегмент из контура. Убранный из контура — меняет.
|
||||||
|
|||||||
@@ -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`.
|
||||||
|
|
||||||
@@ -51,10 +53,15 @@ description: >
|
|||||||
## Два правила (соблюдай всегда)
|
## Два правила (соблюдай всегда)
|
||||||
|
|
||||||
**1. Ориентация печати — первое проектное решение.**
|
**1. Ориентация печати — первое проектное решение.**
|
||||||
- **Спроси у пользователя** (если не задано): главное направление рабочей нагрузки и
|
- **Путь нагрузки и косметические грани из геометрии не выводятся** — их задаёт задача. Спроси
|
||||||
косметические/критичные грани. **Путь нагрузки из геометрии не выводится** — его задаёт задача.
|
пользователя, **если есть кого спрашивать**; работаешь автономно (субагент, пакетный прогон) —
|
||||||
|
выведи из постановки: что деталь держит, куда смотрит рабочая поверхность, чем она крепится.
|
||||||
|
Выведенное — **запиши допущением** в ответ («принято: нагрузка — вес камеры 150 г вниз на плече
|
||||||
|
53 мм; косметика не задана»), чтобы человек увидел, что именно ты предположил. Молчаливое
|
||||||
|
«спросить некого» — не повод пропустить решение об ориентации: без него все дальнейшие правила
|
||||||
|
повисают.
|
||||||
- Реши постановку на стол (ось Z = рост слоёв). От неё зависит: где нависания; куда смотрят
|
- Реши постановку на стол (ось Z = рост слоёв). От неё зависит: где нависания; куда смотрят
|
||||||
отверстия (вертикальные → компенсация Ø; горизонтальные → teardrop); путь нагрузки (**держи в
|
отверстия (вертикальные → компенсация Ø; горизонтальные → по возможности развернуть вертикально); путь нагрузки (**держи в
|
||||||
XY**; Z-сжатие можно, Z-растяжение/срез — нет); плоскости сопряжения (на XY-гранях); «лесенка» на
|
XY**; Z-сжатие можно, Z-растяжение/срез — нет); плоскости сопряжения (на XY-гранях); «лесенка» на
|
||||||
наклонных функциональных поверхностях; если поддержки неизбежны — чтобы опорные грани были
|
наклонных функциональных поверхностях; если поддержки неизбежны — чтобы опорные грани были
|
||||||
некритичными/скрытыми.
|
некритичными/скрытыми.
|
||||||
@@ -65,47 +72,163 @@ description: >
|
|||||||
**FDM-чек-лист** (деталь *печатнопригодна*) — разные проверки. **Гео-аудит
|
**FDM-чек-лист** (деталь *печатнопригодна*) — разные проверки. **Гео-аудит
|
||||||
эвристический и не доказывает печатнопригодность** (не ловит путь нагрузки/анизотропию).
|
эвристический и не доказывает печатнопригодность** (не ловит путь нагрузки/анизотропию).
|
||||||
|
|
||||||
|
## Ориентация: когда три требования не сходятся
|
||||||
|
|
||||||
|
У консольной детали (кронштейн, полка, держатель) требования правила 1 — **нагрузка в XY**,
|
||||||
|
**нависания ≤ `θ_max`**, **опорная площадка** — одновременно невыполнимы. Постоянного приоритета у
|
||||||
|
них нет: он решается ЧИСЛОМ, и число считается за две минуты.
|
||||||
|
|
||||||
|
**Прикидка «прочность против ориентации».** Напряжение в корневом сечении против межслойной
|
||||||
|
прочности — то есть против той самой величины, ради которой требуют «нагрузку в XY»:
|
||||||
|
|
||||||
|
1. `M = F·L` — момент в корне: `F = m·g` (Н), `L` — плечо до корневого сечения (мм) → Н·мм.
|
||||||
|
2. `W = b·h²/6` — момент сопротивления прямоугольного сечения (`h` — размер В ПЛОСКОСТИ изгиба), мм³.
|
||||||
|
Размеры сечения бери `describe_model(sections="box")` или `measure` по граням, а не из головы.
|
||||||
|
3. `σ = M/W` (Н/мм² = МПа).
|
||||||
|
4. Порог — межслойная прочность: доля от XY-прочности по §6 `fdm-rules.md`, для **PLA ~20–30 МПа**
|
||||||
|
(PETG ~15–25, ABS ~8–15).
|
||||||
|
|
||||||
|
**Сечение на пути нагрузки не одно.** Момент проходит через КАЖДОЕ сечение от точки приложения до
|
||||||
|
опоры: корень стойки, место, где она выходит из основания, тонкие ноги основания, перемычку у
|
||||||
|
крепежа. Считай прикидку для всех и бери худшее — замер на кронштейне: корень стойки дал запас 32×,
|
||||||
|
а ноги основания толщиной 4 мм под тот же момент — 3.6×. Самое тонкое место по пути, а не самое
|
||||||
|
очевидное, и решает ориентацию.
|
||||||
|
|
||||||
|
**Точность прикидки — ПОРЯДОК, и в узкой полосе этого мало.** `W = b·h²/6` — это сплошное сечение,
|
||||||
|
а печатная деталь сплошной не бывает: тот же навык требует стенки `n·w` и оставляет заполнение
|
||||||
|
по умолчанию, так что настоящий момент сопротивления корневого сечения заметно ниже габаритного
|
||||||
|
(у оболочки в три периметра на сечении 34×24 — примерно вдвое). Пока запас идёт порядками, это
|
||||||
|
не мешает; в полосе **<3×**, где число и решает, погрешность метода равна ширине полосы. Поэтому:
|
||||||
|
при запасе <3× пересчитайте `W` по фактическому сечению (оболочка `n·w` + заполнение) либо просто
|
||||||
|
возьмите `W` вдвое меньше габаритного и посмотрите, в какой строке таблицы окажетесь.
|
||||||
|
`W` и `I` СПЛОШНОГО фактического сечения (с отверстиями, скруглениями, карманами) не считайте по
|
||||||
|
эскизу — их отдаёт `measure_section(plane, offset)` прямо с построенной детали
|
||||||
|
(`help(topic="section-properties")`); поправка на оболочку и заполнение остаётся вашей.
|
||||||
|
|
||||||
|
| Запас `σ_меж/σ` | Что делать |
|
||||||
|
|---|---|
|
||||||
|
| **< 3×** | «Нагрузка в XY» — жёсткое требование, ориентацию выбирает оно; нависания лечим поддержками, площадку — фланцем, вплоть до разбиения детали (§13) |
|
||||||
|
| **3–10×** | Держать XY, если это не стоит поддержек на функциональных гранях; несущее сечение поднять (§6: ×2 при неизбежной Z-нагрузке) |
|
||||||
|
| **≥ 10×** | Требование СНИМАЕТСЯ — «слои на отрыв» здесь не размерный случай. Ориентацию выбирай по печати: сначала нависания, затем опорная площадка и устойчивость |
|
||||||
|
|
||||||
|
**Пример расчёта** (числа условные — у своей детали бери свои, из постановки и замеров): 150 г на
|
||||||
|
плече 50 мм → `M = 0.150·9.81·50 ≈ 74 Н·мм`; сечение 30×20 → `W = 30·20²/6 = 2·10³ мм³`;
|
||||||
|
`σ ≈ 37 кПа` против ~30 МПа межслойной PLA — запас **три порядка**. Слои тогда не решают ничего, и
|
||||||
|
постановку выбирают по нависаниям, а не по прочности.
|
||||||
|
Без этой прикидки правило «нагрузка в XY» читается как запрет и уводит в худшую по печати ориентацию.
|
||||||
|
|
||||||
|
**Постановки перебирают по граням габарита**, их немного: у плоско-изогнутой детали — две «плашмя»
|
||||||
|
(широкой гранью вниз, посадочной гранью вниз) и одна «стоя» (корневым торцом вниз). Выпиши для
|
||||||
|
каждой три числа — площадь нависающих граней, площадь опорного пятна и `σ` — и выбор перестанет
|
||||||
|
быть спором вкусов. «Стоя» обычно выигрывает по нависаниям и проигрывает по устойчивости; её
|
||||||
|
проверяют отдельно (гео-аудит, проверка центра масс).
|
||||||
|
|
||||||
## Рабочий цикл
|
## Рабочий цикл
|
||||||
|
|
||||||
1. **Калибровка**: сопло→`w`; слой→`h`→`θ_max`; материал→поправки.
|
1. **Калибровка**: сопло→`w`; слой→`h`→`θ_max`; материал→поправки.
|
||||||
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`.
|
Числа — в `references/fdm-rules.md`.
|
||||||
4. **Гео-аудит** (`references/geometry-audit.md`) — инструментами осмотра.
|
4. **Гео-аудит** (`references/geometry-audit.md`) — инструментами осмотра.
|
||||||
5. **Предусловия экспорта**: единое тело/манифолд (`boolean_union` при необходимости) →
|
5. **Предусловия выдачи**: единое тело/манифолд (`boolean` при необходимости) →
|
||||||
построение чистое.
|
построение чистое.
|
||||||
6. **Чек-лист** → экспорт **через `export_model`**: слайсеру нужен `.stl`
|
6. **Чек-лист** → выдача. Обменный файл кладите **только если о нём попросили**: модель самоценна,
|
||||||
(`export_model(path="….stl")` — двоичная сетка), а `.step` остаётся для передачи модели в САПР.
|
а нарезает её человек сам. Попросили — `export_model` (`.stl` — двоичная сетка для слайсера,
|
||||||
|
`.step` — для передачи модели в другую САПР).
|
||||||
|
|
||||||
## Чек-лист печатнопригодности
|
## Чек-лист печатнопригодности
|
||||||
|
|
||||||
- [ ] Направление нагрузки и косметические грани **получены от пользователя**; ориентация
|
- [ ] Направление нагрузки и косметические грани **получены от пользователя или выведены из
|
||||||
зафиксирована; нагрузка в XY (или Z только на сжатие); сопряжения на XY-гранях.
|
постановки и записаны допущением**; ориентация выбрана числом (запас `σ_меж/σ`), а не по
|
||||||
|
умолчанию; нагрузка в XY (или Z только на сжатие, или запас ≥10×); сопряжения на XY-гранях.
|
||||||
- [ ] Стенки кратны `w` (≥2·w; несущие ≥3·w, т.е. 3 периметра); нет «не кратных `w`» (кроме
|
- [ ] Стенки кратны `w` (≥2·w; несущие ≥3·w, т.е. 3 периметра); нет «не кратных `w`» (кроме
|
||||||
функциональных).
|
функциональных).
|
||||||
- [ ] Нет 90°-полок; нависания ≤`θ_max` или заменены скосами; мосты в пределах пролёта по короткой
|
- [ ] Нет 90°-полок; нависания ≤`θ_max` или заменены скосами — отбор ровно в той форме, что в
|
||||||
стороне (числа — `references/fdm-rules.md`); внутренним поддержкам — доступ.
|
§«Гео-аудит»: `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, minZ=<Zmin+0.1>)`
|
||||||
- [ ] Горизонтальные отверстия — teardrop/D (геометрия из `θ_max`); вертикальные — компенсация Ø;
|
(дефолтный допуск 15° ловит только почти горизонтальные потолки, а без `minZ` в улов
|
||||||
глухие — дно ≥2–3 мм.
|
попадает опорное пятно, без `minArea` — микрогрань, которая нависанием быть не может);
|
||||||
- [ ] Фаска у основания (elephant foot); внутренние углы ≥R0.5; опорная площадка есть.
|
пролёт каждого моста **замерен** `measure`, а не прикинут, и
|
||||||
|
укладывается в `references/fdm-rules.md` §2 по короткой стороне; внутренним поддержкам — доступ.
|
||||||
|
- [ ] Горизонтальные отверстия — ось развёрнута вертикально, либо мелкое оставлено круглым, либо
|
||||||
|
D-отверстие; пролёт потолка посчитан и укладывается в норму моста; посадочные — под
|
||||||
|
рассверловку; вертикальные — компенсация Ø; глухие — дно ≥2–3 мм.
|
||||||
|
- [ ] Фаска у основания (elephant foot); внутренние углы ≥R0.5; опорная площадка есть, и для
|
||||||
|
высокой детали проверена устойчивость по §«Гео-аудит»: очертание пятна —
|
||||||
|
`list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)`, проекция ЦМ
|
||||||
|
(`describe_model(sections="mass")`) внутри этого прямоугольника, высота ЦМ над столом
|
||||||
|
≲3× полуширины пятна в узком направлении.
|
||||||
- [ ] Посадки по таблице со **знаком** (натяг — вычесть); допуск ±0.2 **НЕ** прибавлен к зазору;
|
- [ ] Посадки по таблице со **знаком** (натяг — вычесть); допуск ±0.2 **НЕ** прибавлен к зазору;
|
||||||
заходные фаски на сопряжениях.
|
заходные фаски на сопряжениях.
|
||||||
- [ ] Мин. элементы/текст ≥ порогов; аспект тонких выступов ≤4–5×.
|
- [ ] Мин. элементы/текст ≥ порогов (у надписи проверен ШТРИХ, а не кегль: чертёжный шрифт даёт
|
||||||
|
`h/14` и порога не берёт — `references/fdm-rules.md` §7); сторона грани под надпись выбрана
|
||||||
|
так, чтобы она не вышла зеркальной (§10); аспект тонких выступов ≤4–5×.
|
||||||
- [ ] Бобышки/инсёрты (бор отверстия ≤ OD инсёрта, ставить с Z-грани)/резьба/защёлки (изгиб в XY) по правилам.
|
- [ ] Бобышки/инсёрты (бор отверстия ≤ OD инсёрта, ставить с Z-грани)/резьба/защёлки (изгиб в XY) по правилам.
|
||||||
- [ ] Полости — дренаж/вент; критичные поверхности не под «лесенкой»/поддержкой.
|
- [ ] Полости — дренаж/вент; критичные поверхности не под «лесенкой»/поддержкой.
|
||||||
- [ ] Предусловия экспорта: единое тело/манифолд; построение чистое.
|
- [ ] Предусловия экспорта: единое тело/манифолд; построение чистое.
|
||||||
|
|
||||||
## Гео-аудит (кратко)
|
## Гео-аудит (кратко)
|
||||||
|
|
||||||
Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP:
|
Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP — вызовами,
|
||||||
`describe_model` / `list_faces` / `list_faces(index=N)` (нависания по нормалям нижних граней; цилиндры с
|
а не пожеланиями:
|
||||||
горизонтальной осью → нужен teardrop), `describe_model(sections="box")` (как ось слоёв соотносится с габаритом),
|
|
||||||
`measure` (номиналы/зазоры), `describe_model(sections="bodies")` + чистое построение (единое тело). **Границы и методика —
|
- **Цилиндры, конусы и торы этот отбор не видит:** нормаль кривой грани берётся в её центре, и у
|
||||||
`references/geometry-audit.md`.** Аудит эвристический; истинная мин. толщина стенки и полный детект
|
горизонтального цилиндра она горизонтальна. Их проверяй отдельно: `list_faces(type=cylinder|cone)`
|
||||||
криволинейных нависаний не решаются — это **не приговор и не доказательство печатнопригодности**.
|
→ ось (`axis`) горизонтальна — у цилиндра нижняя половина потолка нависает (отверстие — §3
|
||||||
|
`references/fdm-rules.md`), у конуса угол нижней образующей к столу считай из угла конуса.
|
||||||
|
- **Нависания одним отбором:** `list_faces(normal="0,0,-1", normalTolerance=90−θ_max,
|
||||||
|
minZ=<Zmin+0.1>)` — всё вернувшееся кандидаты в нависания, и тем хуже, чем ближе нормаль
|
||||||
|
к чистому −Z (горизонтальный потолок). При дефолтном `θ_max`=45° допуск равен 45 — это совпадение
|
||||||
|
чисел, а не тождество: для PETG с `θ_max`=40° допуск **50**.
|
||||||
|
**`minZ` тут не украшение, а условие правильности.** Отбор по нормали ЗНАКОВЫЙ, а у грани,
|
||||||
|
лежащей на столе, внешняя нормаль равна ровно (0, 0, −1) — она проходит при ЛЮБОМ допуске и
|
||||||
|
выглядит САМЫМ страшным нависанием, хотя это опорное пятно. Замер на кронштейне: тот же отбор
|
||||||
|
без `minZ` (допуск 45°) вернул девять граней, и наибольшая из них — 515.44 мм² с центром ровно
|
||||||
|
на `Zmin` (−50.50) — была пятном первого слоя. Первый слой печатается по столу и нависанием не
|
||||||
|
бывает: отсекайте его окном, `Zmin` берите из `describe_model(sections="box")`.
|
||||||
|
**`minArea` — вторая половина того же отбора.** Угол наклона грани — критерий для ПРОТЯЖЁННОГО
|
||||||
|
нависания; на грани в единицы мм² он не значит ничего, потому что перекрыть надо не угол, а
|
||||||
|
пролёт. Замер: крыша отверстия Ø6, срезанная касательными под 22.5° к горизонтали, приходит в
|
||||||
|
улов как нарушение (нависание 67.5° при пороге 45°) — при площади 2.84 мм² и пролёте 2.30 мм,
|
||||||
|
который печатается заведомо. Ставьте `minArea` порядка 5–10 мм², а всё мелкое, что всё же
|
||||||
|
хотите проверить, судите пролётом (`measure`), а не углом: иначе аудит гонит на редизайн там,
|
||||||
|
где всё в порядке.
|
||||||
|
Дальше `list_faces(index=N)` по подозрительным; цилиндр с горизонтальной осью → проверить пролёт потолка (§3 правил).
|
||||||
|
- **Пролёт моста меряют, а не считают по эскизу:** `measure(kind1="face", index1=…, kind2="face",
|
||||||
|
index2=…)` между ВНУТРЕННИМИ гранями опор (замер: 49.0 мм между стойками). Сравнивать с §2
|
||||||
|
`fdm-rules.md`: 49 мм при потолке PLA 15–25 мм — это редизайн, а не «как-нибудь напечатается».
|
||||||
|
- **Устойчивость высокой печати** — самая дешёвая проверка из всех и единственная, которой нет
|
||||||
|
больше нигде, но стоит она ТРЁХ вызовов, а не одного, и площади пятна для неё НЕ хватает:
|
||||||
|
`list_faces` отдаёт по грани площадь, нормаль и центр — ни границ, ни полуширины из них не
|
||||||
|
выводится. Очертание пятна даёт `list_edges`: он печатает координаты концов рёбер, а окно по Z
|
||||||
|
оставляет только рёбра первого слоя.
|
||||||
|
1. `describe_model(sections="box")` → `Zmin`.
|
||||||
|
2. `describe_model(sections="mass")` → центр масс в мировых координатах (даром).
|
||||||
|
3. `list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)` → концы рёбер пятна; их разброс по X и по Y и
|
||||||
|
есть прямоугольник пятна, а половина меньшей стороны — полуширина в узком направлении.
|
||||||
|
У КРУГЛОГО пятна так не выйдет: у замкнутой окружности концы совпадают, разброс схлопывается
|
||||||
|
в точку. Тогда полуширина — радиус, и берут его `list_faces(index=N)` (у грани печатается
|
||||||
|
радиус) или из длины ребра (`πD`).
|
||||||
|
|
||||||
|
Проверок две: проекция ЦМ `(x, y)` обязана лежать **внутри** этого прямоугольника (у консольной
|
||||||
|
детали «стоя» она легко уходит за него — деталь падает недопечатанной), и высота ЦМ **над столом**
|
||||||
|
(`z_ЦМ − Zmin`) ≲3× полуширины (эвристика; выше — интегральный фланец §5 или разбиение §13).
|
||||||
|
**Пример** (условные числа): габарит `Z −50…180`, ЦМ `(0, 5, 57)`;
|
||||||
|
`list_edges(minZ=−51, maxZ=−49)` вернул четыре ребра — `X −50…50`, `Y 0…8`, то есть
|
||||||
|
пятно 100 × 8 мм. Проекция ЦМ (0, 5) внутри прямоугольника — первая проверка пройдена;
|
||||||
|
высота ЦМ над столом 57 − (−50) = **107 мм** при полуширине узкого направления **4 мм**,
|
||||||
|
это **27×** при пороге 3× — вторая провалена. Сработало именно второе число, и без очертания
|
||||||
|
пятна взять его было неоткуда.
|
||||||
|
- **Тело, габарит, номиналы:** `describe_model(sections="bodies")` + чистое построение (единое
|
||||||
|
тело), `describe_model(sections="box")` (как ось слоёв соотносится с габаритом), `measure`.
|
||||||
|
|
||||||
|
**Границы и методика — `references/geometry-audit.md`.** Аудит эвристический; истинная мин. толщина
|
||||||
|
стенки и полный детект криволинейных нависаний не решаются — это **не приговор и не доказательство
|
||||||
|
печатнопригодности**.
|
||||||
|
|
||||||
**Просвет канала и толщину перемычки спрашивают, а не считают.** `measure(kind1="body", index1=0,
|
**Просвет канала и толщину перемычки спрашивают, а не считают.** `measure(kind1="body", index1=0,
|
||||||
kind2="body", index2=1)` даёт минимальное расстояние между телами целиком — не нужно угадывать, какие
|
kind2="body", index2=1)` даёт минимальное расстояние между телами целиком — не нужно угадывать, какие
|
||||||
|
|||||||
@@ -36,12 +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` к вертикали (с двух
|
с прочностью по слоям (§«Ориентация»).
|
||||||
сторон), сходятся в вершине на вертикальной оси. Высота вершины над центром = **`r / sin θ_max`**;
|
2. **Мелкое отверстие (Ø ≤ ~6 мм) — оставить круглым.** Потолок — короткий мост в пару
|
||||||
включённый угол при вершине = **`2·θ_max`**. При `θ_max`=45° → `r/sin45° = √2·r ≈ 1.414·r` над
|
миллиметров, FDM печатает его без поддержек; круглая часть печатается уже → **+0.1–0.2 мм** к Ø.
|
||||||
центром (= **0.414·r над верхом окружности**), угол 90°. Низ — оставшаяся дуга окружности.
|
3. **D-отверстие** — плоский верх: хорда на высоте `r·cos φ` над центром превращает потолок в мост
|
||||||
|
шириной `2r·sin φ`, материал над хордой остаётся. Контур выреза — ЗАМКНУТЫЙ: дуга окружности
|
||||||
|
снизу от одного конца хорды до другого (`arc3points` по точкам хорды и низу) плюс сама хорда
|
||||||
|
отрезком. Дополнительный вырез поверх круглого отверстия D-формы не даёт — он только
|
||||||
|
расширяет отверстие. Мост держи **≤ 5–10 мм**.
|
||||||
|
Мин. Ø **2 мм**. Посадочные отверстия (вал, подшипник, штифт) после печати рассверливать.
|
||||||
- **Глухое отверстие:** дно = внутренний мост → **толщина дна ≥2–3 мм** или купольное/
|
- **Глухое отверстие:** дно = внутренний мост → **толщина дна ≥2–3 мм** или купольное/
|
||||||
вентилируемое. Сквозные предпочтительнее.
|
вентилируемое. Сквозные предпочтительнее.
|
||||||
- **Отступ от края** — через остаточную перемычку: стенка между отверстием и краем **≥2–3·w**
|
- **Отступ от края** — через остаточную перемычку: стенка между отверстием и краем **≥2–3·w**
|
||||||
@@ -73,6 +78,9 @@
|
|||||||
## 6. Ориентация и прочность
|
## 6. Ориентация и прочность
|
||||||
- **Z (межслойная) прочность от XY:** PLA ~40–55%, PETG ~35–50%, **ABS ~20–35% (выброс)**. Несущую
|
- **Z (межслойная) прочность от XY:** PLA ~40–55%, PETG ~35–50%, **ABS ~20–35% (выброс)**. Несущую
|
||||||
нагрузку — в **XY (вдоль слоёв)**.
|
нагрузку — в **XY (вдоль слоёв)**.
|
||||||
|
- **В абсолютных числах** (нужны, чтобы посчитать запас — SKILL.md §«Ориентация: когда три
|
||||||
|
требования не сходятся»): XY на разрыв PLA ~50–60 МПа, PETG ~45–50, ABS ~35–40 ⇒ межслойная
|
||||||
|
**PLA ~20–30, PETG ~15–25, ABS ~8–15 МПа**. Порядок величины, не паспорт конкретного филамента.
|
||||||
- **Z-сжатие допустимо** (слои в сжатии не расслаиваются); избегать **Z-растяжения и Z-среза**.
|
- **Z-сжатие допустимо** (слои в сжатии не расслаиваются); избегать **Z-растяжения и Z-среза**.
|
||||||
- Изгиб: слои в растяжении/сжатии, не на срез по линии слоя.
|
- Изгиб: слои в растяжении/сжатии, не на срез по линии слоя.
|
||||||
- Z-нагрузка неизбежна → **увеличить несущее сечение** ~×2 относительно XY-расчёта.
|
- Z-нагрузка неизбежна → **увеличить несущее сечение** ~×2 относительно XY-расчёта.
|
||||||
@@ -84,6 +92,13 @@
|
|||||||
- **Выпуклый** текст: штрих **≥0.5 мм**, высота **≥2·h (~0.4 мм)**, sans-serif bold.
|
- **Выпуклый** текст: штрих **≥0.5 мм**, высота **≥2·h (~0.4 мм)**, sans-serif bold.
|
||||||
- **Гравированный** текст: штрих **≥2·w (~0.8–0.9 мм)** (нужно ≥2 периметра; 0.6 мм не влезает),
|
- **Гравированный** текст: штрих **≥2·w (~0.8–0.9 мм)** (нужно ≥2 периметра; 0.6 мм не влезает),
|
||||||
глубина **≥2·h (~0.4 мм)**. (pt не используем — геометрия в мм.)
|
глубина **≥2·h (~0.4 мм)**. (pt не используем — геометрия в мм.)
|
||||||
|
- **Штрих задаёт ШРИФТ, а не кегль, и чертёжные шрифты под печать не годятся.** По ГОСТ 2.304
|
||||||
|
толщина линии чертёжного шрифта равна `h/14`: кегль 8 даёт 0.57 мм — полторы ширины сопла, то
|
||||||
|
есть ниже порога 2·w. Такой шрифт берёт порог только с кегля ~13 мм, а уверенно читаемые 3·w —
|
||||||
|
с ~18 мм. У жирного гротеска штрих ≈ `h/4.5` (Arial Black при кегле 10 → ~2.2 мм), и порог
|
||||||
|
выполняется с запасом уже на кегле 4–5 мм. Замер: «2» кеглем 8 шрифтом GOST type A на
|
||||||
|
вертикальной стенке не читается вовсе; тот же символ кеглем 10 шрифтом Arial Black читается
|
||||||
|
издалека. Маркировку набирайте жирным sans-serif и проверяйте штрих, а не высоту.
|
||||||
|
|
||||||
## 8. «Лесенка» (staircase) — критерий ориентации
|
## 8. «Лесенка» (staircase) — критерий ориентации
|
||||||
- Наклонные/криволинейные поверхности дают ступени: глубина ≈ **`h / tan(α)`** (α — угол от
|
- Наклонные/криволинейные поверхности дают ступени: глубина ≈ **`h / tan(α)`** (α — угол от
|
||||||
@@ -107,6 +122,13 @@
|
|||||||
верхнего слоя (там видны швы и «лесенка»). Тогда деталь и моделируют в этой ориентации — лицом
|
верхнего слоя (там видны швы и «лесенка»). Тогда деталь и моделируют в этой ориентации — лицом
|
||||||
к XOY, — а несимметричный рисунок (логотип, текст) **зеркалят**: на лицевую грань смотрят
|
к XOY, — а несимметричный рисунок (логотип, текст) **зеркалят**: на лицевую грань смотрят
|
||||||
со стороны −Z. Проверка — снимок со стороны лица (`model_snapshot(view=rear)` для эскиза на XOY).
|
со стороны −Z. Проверка — снимок со стороны лица (`model_snapshot(view=rear)` для эскиза на XOY).
|
||||||
|
- **Зеркалит не только лицо на столе — зеркалит ЛЮБАЯ грань, обращённая против нормали эскиза.**
|
||||||
|
Надпись читается с той стороны, куда смотрит нормаль плоскости: XOY → **+Z**, XOZ → **+Y**,
|
||||||
|
YOZ → **−X** (нормаль YOZ уходит в МИНУС X — тот же замер, что разворачивает на ней выдавливание).
|
||||||
|
Значит гравировка по эскизу на YOZ, положенная на щеку с бОльшим X, выйдет зеркальной, а на
|
||||||
|
щеку X=0 — правильной. Замер: цифра на щеке X=20.4 читалась зеркально при ЛЮБОМ `angle`; тот же
|
||||||
|
эскиз, перенесённый на X=0, встал верно. **Поворотом это не лечится** — `angle` вращает, а не
|
||||||
|
отражает; лечится выбором грани (или зеркальным контуром).
|
||||||
- **Фаска по лицевому контуру — это ещё и размер первого слоя.** При 45° она сжимает силуэт лица
|
- **Фаска по лицевому контуру — это ещё и размер первого слоя.** При 45° она сжимает силуэт лица
|
||||||
на катет `c` по всему периметру, поэтому её потолок задаёт не эстетика, а то, что останется:
|
на катет `c` по всему периметру, поэтому её потолок задаёт не эстетика, а то, что останется:
|
||||||
`ширина_штриха − 2c ≥ 2·w`. У широкого рисунка (штрих ~10 мм) ограничением становится толщина
|
`ширина_штриха − 2c ≥ 2·w`. У широкого рисунка (штрих ~10 мм) ограничением становится толщина
|
||||||
@@ -118,24 +140,19 @@
|
|||||||
вписанную окружность, узкое место с координатами и таблицу «офсет `c` → на сколько кусков
|
вписанную окружность, узкое место с координатами и таблицу «офсет `c` → на сколько кусков
|
||||||
распалось лицо» — ничего не строя.
|
распалось лицо» — ничего не строя.
|
||||||
- **Узкое место зависит от СОСТОЯНИЯ контура, поэтому порядок такой: чистка → замер чищеного →
|
- **Узкое место зависит от СОСТОЯНИЯ контура, поэтому порядок такой: чистка → замер чищеного →
|
||||||
катет.** Замеры на обводке логотипа шириной 105 мм (штрих по наибольшей вписанной 11.5 мм):
|
катет.** Чистка (`minSegment`) заменяет скругления острыми углами: в выпуклом углу это добавляет
|
||||||
|
материал, в вогнутом — срезает, а перемычки между штрихами образованы как раз вогнутыми углами.
|
||||||
| контур | узкое место | лицо распадается при |
|
То есть операция, которую делают РАДИ фаски, уменьшает допустимый катет — на обводке логотипа это
|
||||||
|---|---|---|
|
единицы процентов, и хватает, чтобы катет перестал проходить свой же критерий. Мерьте после неё,
|
||||||
| исходный, 54 примитива | 1.98 мм | c = 0.99 |
|
тем же порогом, каким будете строить.
|
||||||
| чищеный порогом 0.5, 34 примитива | **1.82 мм** | **c = 0.91** |
|
- **Норматив катета — `c = stroke_min/2 − w`**, где `stroke_min` — узкое место ЧИЩЕНОГО силуэта,
|
||||||
|
`w` — ширина нити. Он и есть решение неравенства `ширина − 2c ≥ 2w`: в узком месте остаётся
|
||||||
Чистка (`minSegment`) заменяет скругления острыми углами: в выпуклом углу это добавляет материал,
|
ровно `2w`, два прохода сопла. Считайте его на своём контуре — величина принадлежит рисунку.
|
||||||
в вогнутом — срезает, а перемычки между штрихами образованы как раз вогнутыми углами. То есть
|
**Осторожно с «эталонными» значениями из прошлых работ:** катет, принятый когда-то на похожем
|
||||||
операция, которую делают РАДИ фаски, уменьшает допустимый катет. Мерьте после неё.
|
знаке, своему же правилу обычно не удовлетворяет — он подбирался под другой рисунок, другой порог
|
||||||
- **Норматив катета — `c = stroke_min/2 − w`**, где `stroke_min` — узкое место, `w` — ширина нити.
|
чистки или вовсе на глаз. Катет вдвое сверх норматива оставляет в узком месте одну нить экструзии:
|
||||||
Он и есть решение неравенства `ширина − 2c ≥ 2w`. На том же логотипе: `1.82/2 − 0.4 = 0.51`,
|
тело там сплошное, рвётся косметика лицевой грани — та самая поверхность, ради которой деталь и
|
||||||
и в узком месте остаётся ровно 0.80 мм — два прохода сопла.
|
кладут лицом на стол. Сверьте нормативом, а не воспоминанием.
|
||||||
**Осторожно с «эталонными» значениями из прошлых работ:** принятая когда-то на этом логотипе
|
|
||||||
фаска 0.8 собственному правилу НЕ удовлетворяет (`1.82 − 1.6 = 0.22 мм` против нужных 0.8; даже
|
|
||||||
по нечищеному контуру `1.98 − 1.6 = 0.38`). Она оставляет в узком месте одну нить экструзии —
|
|
||||||
тело там сплошное, рвётся косметика лицевой грани, а это как раз та поверхность, ради которой
|
|
||||||
деталь и кладут лицом на стол.
|
|
||||||
- **Верхние рёбра — скругление** (R0.5–2.0); **но** радиус **> ~½ толщины стенки** сам даёт
|
- **Верхние рёбра — скругление** (R0.5–2.0); **но** радиус **> ~½ толщины стенки** сам даёт
|
||||||
нависание > `θ_max` → тогда фаска/ступень.
|
нависание > `θ_max` → тогда фаска/ступень.
|
||||||
- **Внутренние углы — всегда скругление ≥R0.5**.
|
- **Внутренние углы — всегда скругление ≥R0.5**.
|
||||||
|
|||||||
@@ -7,18 +7,45 @@
|
|||||||
|
|
||||||
| Проверка | Как | Статус |
|
| Проверка | Как | Статус |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Нависания (приближённо) | `list_faces`, затем `list_faces(index=N)`: для **нижних** граней угол поверхности от вертикали; > `θ_max` → флаг | ✅ плоские; ⚠️ криволинейные грубо |
|
| Нависания (приближённо) | `list_faces(normal="0,0,-1", normalTolerance=90−θ_max, minZ=<Zmin+0.1>)` — весь улов кандидаты; подробности `list_faces(index=N)` | ✅ плоские; ⚠️ криволинейные грубо |
|
||||||
| Ориентация (геом. прокси) | `describe_model(sections="box")`: как ось слоёв соотносится с габаритом | ⚠️ длинная ось ≠ путь нагрузки |
|
| Ориентация (геом. прокси) | `describe_model(sections="box")`: как ось слоёв соотносится с габаритом | ⚠️ длинная ось ≠ путь нагрузки |
|
||||||
| Горизонтальные круглые отверстия | `list_faces(index=N)`: цилиндр с горизонтальной осью → «нужен teardrop» | ✅ |
|
| Горизонтальные круглые отверстия | `list_faces(index=N)`: цилиндр с горизонтальной осью → пролёт потолка по `fdm-rules.md` §3 | ✅ |
|
||||||
|
| Пролёт моста | `measure(kind1="face", index1=…, kind2="face", index2=…)` между внутренними гранями опор | ✅ |
|
||||||
|
| Устойчивость высокой печати | `describe_model(sections="mass")` — центр масс; `list_edges(minZ=<Zmin−0.1>, maxZ=<Zmin+0.1>)` — очертание опорного пятна по концам рёбер (площадь пятна из `list_faces` для этого не годится) | ✅ проекция ЦМ; ⚠️ порог по высоте — эвристика |
|
||||||
| Номиналы / зазоры / габариты | `measure` между гранями; `describe_model(sections="box")` | ✅ |
|
| Номиналы / зазоры / габариты | `measure` между гранями; `describe_model(sections="box")` | ✅ |
|
||||||
| Тело / манифолд перед выдачей | `describe_model(sections="bodies")` (одно тело?), итог проверки построения в ответе операции | ✅ |
|
| Тело / манифолд перед выдачей | `describe_model(sections="bodies")` (одно тело?), итог проверки построения в ответе операции | ✅ |
|
||||||
|
|
||||||
|
**Почему допуск отбора нависаний равен `90−θ_max`.** `θ_max` меряют от вертикали, а отбор идёт по
|
||||||
|
НОРМАЛИ: у поверхности, наклонённой на `θ` от вертикали, нормаль отстоит от −Z на `90−θ`. Значит
|
||||||
|
нависание (`θ > θ_max`) — это в точности «нормаль ближе `90−θ_max` к −Z». При дефолтном `θ_max`=45°
|
||||||
|
допуск численно равен 45, и это совпадение сбивает: для PETG с `θ_max`=40° правильный допуск **50**,
|
||||||
|
а не 40.
|
||||||
|
|
||||||
|
**И почему у отбора нависаний обязано быть `minZ`.** Отбор по нормали ЗНАКОВЫЙ: грань проходит,
|
||||||
|
если её нормаль отклонилась от заданного направления не более чем на допуск. У грани, лежащей на
|
||||||
|
столе, внешняя нормаль равна ровно (0, 0, −1) — отклонение нулевое, значит она проходит при ЛЮБОМ
|
||||||
|
допуске и по описанному критерию («тем хуже, чем ближе к чистому −Z») выглядит худшим нависанием
|
||||||
|
детали. Замер: тот же отбор без `minZ` (допуск 45°) на кронштейне вернул девять граней, наибольшая —
|
||||||
|
515.44 мм² с центром ровно на `Zmin` (−50.50) — и это опорное пятно, а не нависание.
|
||||||
|
Нижняя граница окна (`minZ = Zmin + 0.1`, `Zmin` из `describe_model(sections="box")`) убирает
|
||||||
|
первый слой из улова.
|
||||||
|
|
||||||
|
**Пролёт и пятно — числа, а не впечатления.** Замеры на кронштейне камеры: пролёт между стойками
|
||||||
|
**49.0 мм** (потолок PLA по §2 `fdm-rules.md` — 15–25 мм, то есть редизайн); опорное пятно
|
||||||
|
«стоя» — `list_edges(minZ=−51, maxZ=−50)` дал четыре ребра, `X −50.50…50.50`, `Y 0.00…8.00`, то
|
||||||
|
есть **101 × 8 мм**, а ЦМ из `sections="mass"` — `(0.00, 4.93, 56.61)`: проекция внутри пятна, но
|
||||||
|
высота ЦМ над столом **107.1 мм** против полуширины **4 мм** — 27× при пороге 3×. Ни то, ни другое
|
||||||
|
не выводится из эскиза арифметикой — оба стоят одного вызова.
|
||||||
|
|
||||||
## Граница честности
|
## Граница честности
|
||||||
|
|
||||||
- **Угол нависания** мерить в **той же конвенции, что fdm-rules.md** (от вертикали; нижняя грань с
|
- **Угол нависания** мерить в **той же конвенции, что fdm-rules.md** (от вертикали; нижняя грань с
|
||||||
поверхностью > `θ_max` от вертикали = нависание) — не путать с углом нормали от горизонтали.
|
поверхностью > `θ_max` от вертикали = нависание) — не путать с углом нормали от горизонтали.
|
||||||
- **Путь нагрузки агент НЕ выводит из габарита** — берёт из задачи/опроса (правило 1). Длинная ось
|
- **Путь нагрузки агент НЕ выводит из габарита** — берёт из задачи, из опроса, а работая автономно
|
||||||
≠ несущая.
|
— из постановки, и тогда записывает допущением (правило 1). Длинная ось ≠ несущая.
|
||||||
|
- **«Нагрузка в XY» — требование с порогом, а не догма.** Обязательность ориентации решает запас
|
||||||
|
`σ_меж/σ` (SKILL.md, §«Ориентация: когда три требования не сходятся»); при запасе ≥10× выбор
|
||||||
|
делают нависания и устойчивость, а не слои.
|
||||||
- **Истинная мин. толщина стенки и полный детект криволинейных нависаний — не решаются** (нет
|
- **Истинная мин. толщина стенки и полный детект криволинейных нависаний — не решаются** (нет
|
||||||
thickness/overhang-солвера).
|
thickness/overhang-солвера).
|
||||||
- **Аудит эвристический и НЕ доказывает печатнопригодность** (не ловит анизотропию/путь нагрузки).
|
- **Аудит эвристический и НЕ доказывает печатнопригодность** (не ловит анизотропию/путь нагрузки).
|
||||||
@@ -29,5 +56,7 @@
|
|||||||
1. После построения, убедившись что оно чистое, — пройти таблицу выше сверху вниз.
|
1. После построения, убедившись что оно чистое, — пройти таблицу выше сверху вниз.
|
||||||
2. Каждый флаг — сверить с соответствующим правилом `fdm-rules.md` и решить: исправить геометрию
|
2. Каждый флаг — сверить с соответствующим правилом `fdm-rules.md` и решить: исправить геометрию
|
||||||
или принять осознанно.
|
или принять осознанно.
|
||||||
3. Путь нагрузки и косметические грани взять из ответа пользователя (правило 1), не из габарита.
|
3. Путь нагрузки и косметические грани взять из ответа пользователя или из постановки (правило 1),
|
||||||
4. Затем — чек-лист печатнопригодности (SKILL.md) → экспорт через `export_model` (`.stl` в слайсер).
|
не из габарита; ориентацию закрыть прикидкой `σ_меж/σ`.
|
||||||
|
4. Затем — чек-лист печатнопригодности (SKILL.md) → выдача; обменный файл (`export_model`) —
|
||||||
|
только если о нём просили.
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "0.4.0",
|
||||||
"tag": "v0.1.0",
|
"tag": "v0.4.0",
|
||||||
"sourceSha": "c7b0387a24cfeae3f19c052eb16d29dcc8030e31",
|
"sourceSha": "f1ecc6ff5a923d524a7aa8dc7b97c538d9cf1bb3",
|
||||||
"built": "2026-08-06T21:03:33Z"
|
"built": "2026-10-15T03:15:33Z"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user