Files
kompas-plugin/plugin/skills/kompas-3d/SKILL.md
T

69 KiB
Raw Blame History

name, description
name description
kompas-3d Методика работы с КОМПАС-3D через MCP-сервер плагина: построение и модификация деталей, импорт/экспорт STEP, работа со сборками, осмотр геометрии снимками и запросами. Используй ВСЕГДА, когда задача — что-то СДЕЛАТЬ в КОМПАС через MCP-инструменты (создать/править деталь, импортировать STEP, разобрать сборку, померить, отрендерить, экспортировать). Здесь — playbook'и и эвристики, проверенные на практике. Триггеры: «построй деталь в КОМПАС», «импортируй STEP», «что в этой сборке», «нарасти/измени деталь», «экспортируй STEP», «сделай снимок модели».

kompas-3d — методика управления КОМПАС-3D через MCP

MCP-сервер даёт общие операции КОМПАС (эскизы, формообразующие, осмотр, обмен), этот навык — методику: в каком порядке их применять, как выбирать геометрию, чем проверять результат и какие подводные камни обходить. Коротко: MCP = чем делать, навык = как делать. Подробности вызова — варианты операций, обязательные поля, типы примитивов эскиза и их параметры — живут в описаниях самих инструментов: контракт сервера подробен, читай его, а не восстанавливай по памяти.

Когда применять

Любая задача «сделать что-то В КОМПАС» через MCP: создать/править деталь, эскизы и операции, импорт/экспорт обменных форматов, разбор сборки, измерения, снимки.

Два правила прежде всего

1. «Зрение» — структурное, не по картинке. «Увидеть» деталь = describe_model — паспорт одним запросом и ЕДИНСТВЕННЫЙ инструмент осмотра: разделы box | mass | bodies | topology | tree | variables | errors | components (sections сужает и ответ, и объём чтения модели). Углубляться — list_faces(index=N) / list_edges (отбор type + координатное окно — им адресуют то, что не выбрать по одному: весь нижний контур под фаску) / measure. model_snapshot бери только для визуально-пространственных вопросов, на которые паспорт не отвечает (общая форма, ориентация, правдоподобность, «куда смотрит грань»): снимок дорог по контексту и менее точен, чем числа.

1а. Осмотр НЕ перестраивает документ. Если модель правили снаружи (человек в GUI, соседний агент) или операция запросила перестроение, describe_model покажет числа ДО правки — и ответ будет выглядеть безупречным: размеры новые, положения старые, сопряжения валидны. Такой ответ сам скажет «Документ ТРЕБУЕТ ПЕРЕСТРОЕНИЯ» (needsRebuild: true); увидел — rebuild и повтори осмотр, выводов по непересчитанной модели не делай.

2. Ответ мутирующей операции — это ТРИ проверки, читай все. Любая операция может «пройти» (Create()==true), оставив деталь в ошибке, поэтому каждая мутирующая операция сама дописывает к ответу итог проверки построения и сводку состояния «Тел: N, объём V мм³»:

  • «⚠ N операц. в ошибке» (напр. et3dError54) — деталь невалидна: не продолжай и не экспортируй, исправь или переделай другим методом. «Построение чистое» = порядок. Строки с «ℹ» — не отказы: «требуется перестроение» лечится rebuild, а «не определено положение (N)» означает, что компоненту не хватает сопряжений или фиксации. Бросать из-за них исправную сборку не нужно; в обеих названы имя и индекс компонента.
  • «Тел: 2» там, где ждёшь одно тело, — деталь распалась: касание объединением не считается (см. «Надписи»). Смотри на число ТЕЛ, а не граней: объединение сливает компланарные грани, и счётчик граней законно остаётся прежним.
  • Объём сверяй с прикидкой «площадь контура × высота». Так ловятся молча не применившаяся тонкая стенка (прирост как у сплошного сечения), вычитание мимо цели и операция «не туда» — габарит и снимок этого не покажут.

Отдельный describe_model(sections=errors,bodies,mass) после каждого шага не нужен. Он возвращается, когда авто-проверку выключили (set_auto_validate(false) на тяжёлой модели, где проверка каждого шага тормозит): тогда describe_model(sections=errors,bodies,mass) вручную перед выдачей: одного errors мало — распад детали на два тела показывает только раздел bodies.

Справочник сервера: help

Подробности инструментов — маршруты, порядок вызовов, ловушки — лежат в самом сервере и достаются по требованию, а не занимают контекст заранее:

  • help() — оглавление тем (дёшево, одна строка на тему);
  • help(topic="…") — статья целиком;
  • help(query="…") — поиск словами с цитатами;
  • help(tool="extrude") — что известно про конкретный инструмент.

Зови его, когда инструмент повёл себя не так, как ты ожидал, и когда тема названа в тексте ошибки. Ссылки вида help(topic="…") по этому файлу — не украшение: там лежит то, что здесь намеренно не повторяется. Справочник описывает ЭТОТ сервер; справка по COM API КОМПАС — отдельная история и в работе через MCP не нужна.

Инструменты: индекс групп

Актуальный перечень с описаниями параметров отдаёт сам MCP-сервер — здесь только карта:

  • Система/документы: kompas_connect (shared|private|attach), kompas_set_visible, kompas_status, set_auto_validate, set_operation_log; document_create|open|save|close, document_active (тип, путь, есть ли несохранённые изменения, «только чтение», материал детали), document_list (все открытые документы — им проверяют, что имя файла занято другим документом и что несохранённого не осталось), set_part_info, set_part_material.
  • Эскиз: sketch_create (основание: plane+offset | faceIndex | точка; геометрия — списком entities или файлом entitiesFile), sketch_add, sketch_close; measure_text — замер надписи без построения; fragment_create — тот же список примитивов, но в самостоятельный файл-фрагмент (*.frw); fragment_place — положить готовый фрагмент в чертёж.
  • Формообразующие: primitive, extrude, revolve, fillet_edge, chamfer_edge, shell, rib, sweep, loft, draft, hole, pattern, mirror, feature_delete, rebuild.
  • Прямое редактирование (в т.ч. импортированная B-rep): move_face, split_solid_by_plane, move_body, boolean_union.
  • Переменные: set_variable, list_parameters, link_parameter, delete_variable (сами переменные показывает describe_model(sections=variables)).
  • Обмен: import_model (3D: step, iges, sat, xt, stl, c3d, jt, obj + родные форматы чужих САПР), import_drawing (плоский .dxf/.dwg), export_model (format=auto по расширению: .step — точная геометрия в другую САПР, .stl — сетка в слайсер).
  • Исполнения: embodiment (set|add|delete|rename; kind=embodiment|mirror|variant) — несколько геометрий одной модели в одном файле; список с габаритом и массой каждого — describe_model(sections=embodiments).
  • Сборка: assembly_add_component (положение + поворот rx/ry/rz, embodiment — какое исполнение источника вставлять), assembly_add_mate (стороной может быть грань ИЛИ вспомогательный объект object1/object2: плоскости и оси СК компонента, а без componentIndex — самой сборки) (семь типов, orientation), assembly_fix_component, assembly_delete, assembly_check_interference (не налезли ли детали друг на друга — больше это не видно нигде), assembly_transform_point (to=world|local — точка между ЛСК компонента и СК сборки).
  • 2D-чертёж: drawing_create_standard_views (views[], mainOrientation, hiddenLines), drawing_add_view / drawing_move_view / drawing_delete_view / drawing_get_view_info (компоновка листа и паспорт вида), drawing_add_section_view (РАЗРЕЗ или СЕЧЕНИЕ: линия разреза на базовом виде и производный вид по ней — одним вызовом), drawing_add_sheet, drawing_set_sheet_format, drawing_fill_title_block, drawing_add_linear|diametral|radial|angular_dimension (у всех — tolerance/prefix/suffix/ textOverride; у Ø и R — ещё objectKind/objectIndex, прямой адрес окружности или дуги), drawing_add_axis, drawing_add_rough|text|leader, drawing_set_unspecified_rough, drawing_set_technical_requirements, drawing_delete_object, drawing_move_object (сдвинуть поставленное), drawing_project_point (точка модели → координаты вида), drawing_export_image (посмотреть глазами). Обратное чтение — drawing_get_title_block и drawing_get_technical_requirements: технические требования ПЕРЕЗАПИСЫВАЮТСЯ целиком, поэтому правку одного пункта начинают с чтения текущего текста. Методика — §«Чертёж».
  • Осмотр: describe_model (разделы box|mass|bodies|topology|tree|variables|errors|components|mates — габарит, МЦХ, тела, топология, дерево построения, переменные, операции в ошибке, состав сборки, сопряжения), measure, model_snapshot; адресация объектов — list_faces / list_edges. Для 2D-документов — свой: list_drawing_objects (что лежит в чертеже/фрагменте).

Три сквозных свойства контракта: размерный параметр принимает число ИЛИ выражение (имя переменной/формулу — параметр сразу становится ведомым); объект выбирается индексом (надёжно) или точкой (запасной путь — если выбирал точкой, ответ подскажет, что выбралось); списковые параметры (entities[], edgeIndices[], points[], faceIndices[], variables[], links[]) — весь пакет одним вызовом: прямоугольник с четырьмя отверстиями — ОДИН sketch_create, скругление восьми рёбер — ОДИН fillet_edge, крепёжная картина из шести отверстий — ОДИН hole(points=[…]), наращивание двух торцов — ОДИН move_face(faceIndices=[…]); каждый лишний вызов — лишний шанс сбиться. Пакет НЕ транзакционен: отказ называет позицию элемента в списке, а сделанное до него остаётся — повторяй вызов с оставшимися, а не с начала. Если инструмента под задачу нет — собирай результат из имеющихся общих операций.

Два пути формообразования — выбирай по форме, а не по привычке

«Эскиз → выдавливание» — не единственный способ. primitive строит тело сразу по размерам, и это короче и надёжнее там, где форма призматическая:

Форма Чем строить
Плита, брусок, бобышка, штифт, цилиндрическая стойка primitive(kind=block|cylinder) — один вызов вместо «эскиз + выдавливание»
Прямоугольный карман, паз, срез угла primitive(..., result=subtract) — вычитание тела вместо extrude(mode=cut) по эскизу
Скруглённые углы призмы primitive + fillet_edge по рёбрам (скругление после, а не дуги в эскизе)
Текст, кривые, произвольный контур, переменное сечение ТОЛЬКО эскиз: sketch_create(entities=[…]) + extrude/revolve/loft/sweep
Тонкая стенка, ободок по контуру эскиз + extrude(thinThickness, thinSide)

Их сочетают в одной детали: корпусные объёмы — примитивами, сложные контуры — эскизами.

  • Ось цилиндра и конуса задаётся параметром, а не системой координат детали: primitive(kind="cylinder", axis="X"|"Y"|"Z"). Точка x,y,z остаётся центром основания в мировых координатах, высота растёт вдоль выбранной оси. Не перепроектируй деталь ради того, чтобы её ось совпала с Z (у block и sphere параметра нет: у блока ось задают размеры length/width/height, у сферы оси нет).

  • Тонкую стенку по сложному контуру строй ДО того, как появится тело, которое она пересечёт. extrude(thinThickness=…) по многоконтурному эскизу (надпись — десяток замкнутых контуров с «дырками») отказывает, если стенка пересекает уже построенное тело; простой прямоугольный контур проходит и с пересечением. Ошибка сервера называет причину, но порядок планируй заранее: на шильдике «плашка → буквы → кайма» падает, а «буквы → кайма → плашка primitive(union) → карман primitive(subtract)» проходит — примитивам пересечение безразлично.

  • Скругления делай, пока рёбер мало — сразу после примитивов их видно в list_edges наперечёт. Если рёбер уже сотни, бери их ПО ТОЧКАМ: fillet_edge(radius, points=[…]) по углам известных координат — одна операция на все; точки без ребра ошибка перечислит разом.

  • Скругление не построится там, где ребро «съедено» соседним элементом (угол плашки под каймой букв). Это нормальный ответ геометрии, а не ошибка вызова: проверь снимком, виден ли угол снаружи.

  • result=new даёт ОТДЕЛЬНОЕ тело, subtract мимо цели сервер ловит сам — и то и другое видно по сводке «Тел/объём» в ответе; при распаде зови boolean_union.

Базовый цикл (эскиз → операция → осмотр)

Опорный сценарий построения, проверен end-to-end:

  1. kompas_connect (+ kompas_set_visible true). Работаешь не один — бери свой экземпляр: kompas_connect(instance="private") (см. «Когда КОМПАС общий»).
  2. document_create(type="part", name="…") — наименование даём сразу, здесь оно ничего не стоит.
  3. Запиши замысел переменными до первого эскиза (см. «Параметризация») и связывай каждый размер, взятый из паспорта, при построении — иначе переменная останется числом в списке.
  4. sketch_create(plane="XOY", entities=[…]) — весь контур одним вызовом.
  5. extrude / revolve → прочитай итог проверки и сводку прямо в ответе (правило 2).
  6. Осмотр — структурно: describe_model (нужен кусок — sections="box,mass").
  7. Итерация «на грани»: list_facessketch_create(faceIndex=N, entities=[…]) → операция.
  8. Задай материал, если смотришь на массуset_part_material: у нового документа стоит сталь 7.86, и МЦХ печатной детали завышена вшестеро; плотности ходовых материалов перечислены в описании инструмента.
  9. Проверь, что деталь названа (шаг 2 или set_part_info) — безликая «Деталь» уедет в штамп чертежа и спецификацию; имя файла при сохранении этого не заменяет.

Называй каждую операциюname есть у всех: «Контур плашки», «Рельеф букв OldMan», «Карман под площадку». Дерево из «Эскиз:1, Элемент выдавливания:3» нечитаемо ни человеку, ни тебе самому через сотню вызовов.

Параметризация: сначала переменные, потом геометрия

В новом документе первым делом опиши будущую модель переменными — до первого эскиза. Пока деталь пуста, компоновка стоит одного вызова на размер; после десятка операций та же мысль стоит пересборки. Набор переменных — это план построения числами и паспорт, по которому человек поймёт модель, не разбирая дерево.

  • Заводи переменной то, что было РЕШЕНИЕМ: габариты из ТЗ, толщины, зазоры, отступы, кегли, радиусы. Выводимое задавай формулой (plate_L = badge_L - 2*edge_gap) — правка ведущего размера пересчитает зависимые сама. Позиции, подобранные замером, оставляй числами: связь — обещание, что правка переменной даст осмысленный результат, а на позиционных числах она чаще ломает деталь.
  • Размер передавай выражением прямо в операцию (extrude(depth="badge_T")) — параметр сразу становится ведомым, внутреннее имя параметра («Расстояние 1») знать не нужно. Переменная должна существовать ДО операции — потому паспорт и заводят первым. Задним числом и для параметров, которых нет среди аргументов инструмента (углы уклона, второе направление), — link_parameter.
  • Промахи сервер ловит сам: ссылка на несуществующее имя — отказ с перечнем виновных (и в выражениях операций, и в set_variable; регистр значим), функции в формулах — предупреждение (тригонометрия в радианах, разделитель аргументов «;», непонятая запись = молчаливый 0). Твоя часть — сверить вычисленные значения из ответа со своей прикидкой.
  • note обязателен и пишется по-русски, со смыслом и единицей; (ТЗ) метит числа, зафиксированные пользователем. Что замерил — верни в переменную (фактический кегль, прирост каймы), иначе паспорт разойдётся с моделью и станет дезинформацией. Переосмысливать можно всё, кроме помеченного (ТЗ).
  • После связывания правка паспорта перестраивает деталь (проверено: set_variable(badge_T=4) → габарит по Z 3.00 → 4.00, объём 5154.5 → 5861.5 мм³). Это и есть параметрическая модель, а не комментарий к ней. До связывания — не перестраивает, и set_variable говорит об этом прямо: «⚠ НИЧЕГО НЕ ВЕДЁТ». Такой ответ — не успех: число поменялось, деталь нет.
  • Сверка и уборка в конце: describe_model(sections=variables) помечает «⚠ ничего не ведёт» — это либо забытая связь, либо мусор; разбери оба. delete_variable(unused=true) — только ПОСЛЕ link_parameter на всё, что должно вести геометрию: вычистка не отличает мусор от несвязанного размера из ТЗ.

Надписи, логотипы и рельеф

Надпись — примитив type=text в эскизе; все поля (шрифт, кегль, widthFactor, выравнивание align/vAlign) описаны в схеме entities. Она сразу переводится в кривые, поэтому выдавливается как обычный контур: гравировка — extrude(mode="cut"), выпуклые буквы — mode="boss".

  • Ответ даёт габарит ГЛИФОВ и ширину ячейки — позиционируй по глифам. Ячейка шире на 1–2 % у наборных шрифтов (Zilla Slab, Bevan) и на 79 % у скриптовых (Lobster, Pacifico).
  • Кегль калибруй measure_text — он ничего не строит. Пробу, которую всё же пришлось построить, убирает feature_delete; отдельный черновой документ для этого не нужен.
  • height — высота ПРОПИСНОЙ, а не габарит строки (Zilla Slab, height=10: «HH» → 9.97 мм, «Hy» → 13.24 мм, выносной уходит на −3.27) — закладывай выносные отдельно. Прочие тонкости полей (widthFactor, align, vAlign) — help(topic="sketch-text").
  • Подложка под надпись — тем же эскизом тонкой стенкой: один хендл эскиза можно передать в несколько операций — сплошное выдавливание на высоту подложки + extrude(thinThickness, thinSide="outward") дают силуэт с равномерной каймой. Стенку проверяй по объёму из сводки: не применившаяся толщина молча даёт сплошное сечение при том же габарите.
  • Надпись и плашка обязаны ПЕРЕКРЫВАТЬСЯ — по размерам чертежа блоки обычно только касаются, а касание объединением не считается. Приём: кайму/полосу плашки сделать выше самой плашки на 1–1.5 мм с той стороны, где стоит надпись. Распад видно по «Тел: 2» в ответе операции — не тяни проверку до конца построения.
  • Рельеф = разница глубин от одной плоскости (основание 2 мм + буквы 3 мм = выступ 1 мм); не строй буквы «на грани основания» — из одного эскиза на базовой плоскости получается и то и другое, и рельеф не зависит от порядка операций.
  • Шрифт должен быть установлен в системе — неизвестное имя КОМПАС молча подменяет; сервер предупреждает об этом в ответе sketch_create/measure_text — не игнорируй.

Логотип, которого нет в шрифте, приходит готовым вектором (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 — ширина нити.

Менять шаги местами нельзя: чистка СУЖАЕТ узкое место. Она заменяет скругление острым углом — в выпуклом углу это добавляет материал (габарит подрастает), а в вогнутом срезает его, и именно вогнутые углы образуют перемычки между штрихами. Замер обводки логотипа шириной 105 мм: узкое место 1.98 → 1.82 мм, порог распада лицевой грани 0.99 → 0.91. Катет, подобранный по нечищеному контуру, после чистки перестаёт проходить свой же критерий.

  • Ширину штриха и узкое место меряй инструментом, а не глазомsketch_measure_thickness ничего не строит и документа не требует, поэтому зовётся ДО эскиза (help(topic="silhouette-thickness")). От этих чисел зависит, останется ли что-то от рисунка после фаски и напечатается ли он вообще; шаг растра в ответе — точность округления катета.

Контур, который переживёт конкретную деталь (логотип, шаблон, профиль), клади во фрагмент — fragment_create(path, entities) тем же списком примитивов. Активный документ он не подменяет, поэтому фрагмент можно снять посреди построения детали; габарит в ответе снят с самого документа — сверяй его с задуманным.

Точная подгонка и отделка — в 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 → проверить. Разбор чужой сборки — следующий раздел, здесь про сборку с нуля.

  1. Детали сначала сохрани в файлы. Компонент вставляется ссылкой на .m3d/.a3d, поэтому несохранённую деталь вставить нельзя.
  2. document_create assemblyassembly_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"); про локальные координаты граней и pointOnFacehelp(topic="face-addressing").

Чертёж: оформить деталь по ГОСТ

Чертёж строится не так, как деталь: авто-валидации здесь нет. Правило трёх проверок из §«Базовый цикл» в 2D не работает — операция не отчитывается «построилось верно», потому что верность тут не про геометрию, а про место на листе. Проверять приходится самому, и способ ровно один: посмотреть.

Порядок, который окупается:

  1. Деталь строится в чертёжной ориентации. Набор видов задаётся ОТ модели: mainOrientation выбирает, какую ориентацию модели показывает главный вид, но саму ориентацию модели он не вращает. Если самая информативная проекция детали — не одна из шести стандартных, чертежа по ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость с наибольшей информацией.
  2. drawing_set_sheet_format (формат до видов — иначе виды придётся двигать), при необходимости drawing_add_sheet для второго листа.
  3. drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…) — бери ровно те проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. Главный вид входит в набор сам: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому views=["top"] даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими.
  4. Координаты — замером, а не формулой. drawing_get_view_info(viewNumber) отдаёт паспорт вида одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид арифметикой; отдельные точки переводит drawing_project_point(x, y, z, viewNumber). Выводить оси из головы не надо и вредно: у КОМПАС «спереди» показывает плоскость XY детали, а «сверху» — X и минус Z, и знаки инверсии зависят от mainOrientation — формула, выведенная на одном чертеже, на соседнем врёт.
  5. Разрез — до размеров, а не после. Внутреннюю геометрию (зенковка, ступенчатое отверстие, паз, глубокая расточка, полость) показывай разрезом, а не невидимыми линиями: по штриховой линии нельзя ни поставить нормальный размер, ни разобрать форму. drawing_add_section_view — см. §«Разрез» ниже. Размеры внутренней геометрии ставятся УЖЕ НА РАЗРЕЗЕ, поэтому строить его надо раньше простановки, иначе размеры придётся переносить.
  6. Размеры, drawing_add_axis (осевые и центровые), шероховатость, выноски, техтребования, штамп. Осевые сначала посмотри, потом добивай: ассоциативные виды приходят со СВОИМИ центровыми и осевыми, которые КОМПАС ставит сам, и drawing_add_axis вслепую даёт дубли поверх существующих. Сначала list_drawing_objects(kind="axis"|"centreMarker", viewNumber=…).
  7. drawing_export_image — посмотреть глазами. Пока картинки не было, чертёж не сдан.

Разрез

drawing_add_section_view делает всё сразу: проводит линию разреза на базовом виде и строит по ней производный вид со штриховкой. Механика, ступенчатый разрез и встроенная проверка честности — help(topic="drawing-sections"); здесь только решения, которые принимаешь ты:

  • Разрез или hiddenLines. Разрез — когда внутреннее нужно ИЗМЕРИТЬ или показать форму: зенковка и цековка, ступенчатое или резьбовое отверстие, паз, канавка, глубокая расточка, тонкая стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к штриховой линии не привязывают.
  • Веди линию с запасом за габарит (плита 60 мм → от −40 до +40): линия по самому краю режет не всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт drawing_get_view_info.
  • Строй разрез, когда модель готова: после правки детали перестраивается только ПЕРВЫЙ разрез базового вида. Модель всё же изменилась — снеси разрезы и построй заново.
  • Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру.

Промах простановки лечится, а не остаётся навсегда. Отката (undo) у чертежа нет, но list_drawing_objects показывает обозначения с индексами, drawing_delete_object убирает одно, а drawing_move_object его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не заменой размера на выноску. Так же правится и компоновка: drawing_move_view переставляет вид со всеми обозначениями, drawing_add_view доносит недостающую проекцию, drawing_delete_view убирает лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления — help(topic="drawing-fixing").

Три вещи, на которых чертёж молча выходит неверным — держи их в голове, детали в справочнике:

  • viewNumber=0 — это НЕ главный вид, а координаты ЛИСТА; знак, поставленный «на главном виде» с нулём, уезжает за границы формата (help(topic="drawing-views"));
  • ассоциативны только диаметральный и радиальный размеры; линейный и угловой меряют координаты, и «60» останется, когда деталь станет 70 — после правки модели перепроверяй их сам (help(topic="drawing-dimensions"));
  • допуск, не легший в размер, виден только по пустому read-back в ответе — техтребования его не заменят (help(topic="drawing-dimension-text")).

Ещё две ловушки, о которых узнаёшь только столкнувшись: штамп частично ведёт МОДЕЛЬ, а не чертёж (help(topic="drawing-title-block")), и у цилиндрической грани нет «координат оси» — её восстанавливают и проверяют сходимостью площадей (help(topic="cylinder-axis")).

Чего нет. Выносного элемента (увеличенный фрагмент), МЕСТНОГО разреза внутри вида, местного вида и вида с разрывом. Ассоциативного ЛИНЕЙНОГО размера нет и не будет: в API у него нет привязки к геометрии ни под каким именем (проверено QI, поздним связыванием и размером с обрывом). Экспорта в PDF/DXF тоже нет — наружу уходит растр (drawing_export_image) и STEP.

Работа с импортом / сборками

Конвейер «импорт → разбор → извлечение детали → осмотр → модификация → экспорт»:

  1. import_modeltype задаёт документ: assembly (по умолчанию) или part. Формат берётся из расширения; .prt и .asm носят несколько САПР сразу — там задавай format явно. Нужна отдельная деталь файлом — включай createComponentFiles: без него импорт не пишет на диск ничего, кроме открытого документа. Плоский чертёж (.dxf/.dwg) читает не он, а import_drawing.
  2. Разбор: describe_model(sections=components) (у каждого компонента — origin, поворот, фиксация) и describe_model(sections=mates), если сборка пришла со связями; грани компонента — list_faces(component=N). Извлечённую деталь открывай самостоятельным документом. Гашение видимости компонента на снимок не влияет — изоляция так не делается.
  3. Осмотр — структурно (describe_model: какая ось «высота», МЦХ, топология). Снимок model_snapshot(view=…) — ракурс выбирай по плоскости детали (плоскую смотри сверху или спереди, не в изометрии); один и тот же view даёт воспроизводимый кадр «до/после». Пары ракурсов противоположны по оси: front смотрит из +Z, rear — из Z, так же top/bottom и left/right. Следствие, которое нужно чаще всего: деталь, лежащая на столе гранью Z=0 (эскиз на XOY, выдавливание вперёд), видна столу как rear, а front покажет зеркальную картинку. Читаемость надписи или логотипа доказывают снимком с нужной стороны, а не рассуждением.
  4. Модификация «тупой» B-rep (итог — в ответе каждой операции): простой случай — move_face; вставка N мм в призматическую ножку — split_solid_by_planemove_bodymove_face (мост) → boolean_union (шаги пронумерованы в описаниях самих инструментов; цепочка проверена end-to-end: проставка 39.45 → 41.45 мм, построение чистое).
  5. Перед выдачей: последняя операция «Построение чистое» → export_model (STEP для обмена, STL для печати).

Исполнения: одна модель — несколько геометрий

Типоразмеры (профиль на 100, 200, 500 мм), правое и левое зеркало, версии с отверстием и без часто живут в одном файле исполнениями. Тогда всё, что ты меришь и экспортируешь, относится к текущему исполнению — не к «детали вообще».

  • Признак замечаешь не ты, а ответ. У модели с несколькими исполнениями describe_model сам пишет, сколько их и какое сейчас текущее. Увидел эту строку — прежде чем считать массу или резать чертёж, посмотри describe_model(sections=embodiments): там габарит и масса каждого, и это чтение ничего не переключает.
  • Переключение равно смене документа. embodiment(action="set", target="L200") обнуляет сессию построения: хендлы sk_…/op_… после него мертвы. Сохраняй документ до переключения.
  • Индекс живёт до первой правки дерева: после delete индексы смещаются. Адресуй обозначением («L500»), а индексом — только сразу после того, как увидел список.
  • Строишь новое исполнениеembodiment(action="add", number="02"); оно сразу становится текущим, строй в нём немедленно. depended=false нужен, когда правки НЕ должны наследоваться от родителя, — иначе изменение уедет и в него.
  • В сборку исполнение выбирается явно: assembly_add_component(embodiment="L500"). Без параметра встанет базовое исполнение, а не то, что сохранено в файле текущим. Обозначение нужно ПОЛНОЕ («ПРОБА.001-01», а не «-01»); сервер откажет, если КОМПАС подсунет базовое.
  • «Удлинить эти профили с 500 до 600» — это смена исполнения экземпляра, а не новая вставка: embodiment(action="set", target="L600", component=N) и затем rebuild. Сопряжения при этом сохраняются — пересоздание вставки, наоборот, порвало бы их все. Какие исполнения есть у конкретного экземпляра, показывает describe_model(sections="embodiments", component=N).
  • Выгнать всю линейку на печатьexport_model(embodiment="all"): каждое исполнение в свой файл с суффиксом обозначения.
  • После смены исполнения в собранном узле проверь сопряжения (sections="mates"): если у нового исполнения нет объекта, на который опиралась связь, она рвётся — «ССЫЛКА ПОТЕРЯНА», valid: false, компонент недоопределён. Что было потеряно, хранит имя сопряжения; assembly_delete сотрёт и его.

Подробности и границы — help(topic="embodiments").

Эвристики и подводные камни

  • Правила 1 и 2 действуют всегда: осмотр структурный; «⚠ N операц. в ошибке» — в STEP/печать не брать.
  • Направление операции (extrude(forward), знак distance у move_face): на выбранной грани зависит от ориентации её нормали — реши ДО построения, прочитав нормаль в list_faces(index=N) (или по снимку), а после сверь сводку объёма в ответе.
  • Эскизы и операции адресуются ХЕНДЛАМИ из ответовsk_7c1e5aa3f1_1_2, op_7c1e5aa3f1_1_5. Не сочиняй их и не передавай числа: числовая адресация не поддерживается, а сервер объяснит формат отказом. Хендл живёт только в текущей сессии построения: смена активного документа (create/open/close) и перезапуск сервера делают прежние хендлы мёртвыми, и они отказывают с указанием причины — не молча, как раньше делали числовые id. Потерял хендл — читай describe_model(sections=tree) и строй заново; сохраняйся перед долгими паузами. Хендл — это НЕ индекс: faceIndex/edgeIndices из list_faces/list_edges и параметр feature у link_parameter/list_parameters (имя или индекс узла дерева) остаются числовыми. primitive и hole тоже возвращают хендл (у hole — по одному на КАЖДОЕ отверстие серии), так что примитив и отверстие можно удалить feature_delete и размножить pattern/mirror. Если ответ вместо хендла говорит «выдать не удалось» — операция построена, но адресовать её нечем: переставить её потом можно только пересборкой.
  • Единицы — мм (геометрия) и кг (масса). Локальные координаты эскиза ≠ мировые координаты модели.
  • Одинаковая ошибка у ВСЕХ инструментов — это транспорт, а не КОМПАС. «Unable to connect…», таймаут или пустой ответ на kompas_connect, kompas_status и describe_model одновременно означают, что до MCP-сервера не дошёл ни один байт: перебирать инструменты и «пробовать ещё раз» бесполезно. Один-два подтверждающих вызова — и сдавай задачу как заблокированную, назвав, что именно не отвечает. Отдельный признак того же — сообщение без имени инструмента и без слова «КОМПАС»: наши ошибки всегда называют операцию и причину.

Когда КОМПАС общий

По умолчанию (instance="shared") сервер работает в том же экземпляре КОМПАС, что человек и другие агенты, а активный документ там один на всех. Два симптома, которые легко принять за свою ошибку: операция ушла в чужую деталь (кто-то создал документ — активность переехала), либо твой документ исчез, потому что сосед вызвал document_close(all=true) — тот закрывает ВСЁ и без сохранения.

  • Строишь параллельно с кем-то — instance="private" при первом kompas_connect (потом режим не сменить). Свой экземпляр: активный документ только твой, окно скрыто (kompas_set_visible true покажет).
  • shared оставляй, когда работа идёт на глазах у человека и ты единственный агент.
  • Один файл в двух экземплярах не открыть — второй получит его только на чтение: работу делите по файлам, а не по вкладкам.

Открытые вопросы / границы

  • Параметрика работает через параметры ОПЕРАЦИЙ, а не размеры эскиза — сдвинуть контур переменной нельзя, только пересобрать эскиз. Планируй членение так, чтобы изменяемое задавалось параметром операции (глубина, радиус, габарит примитива), а не координатами в эскизе.
  • 2D покрыт вместе с разрезом и сечением. Есть виды (с выбором набора, ориентации главного и невидимых линий), разрез/сечение, листы, штамп, размеры с допусками, осевые, обозначения, техтребования, удаление и сдвиг объекта, вывод в растр — методика в §«Чертёж». Нет выносного элемента, местного разреза внутри вида, местного вида и вида с разрывом.
  • Разрез не переживает правку модели, если он не первый на своём базовом виде. Замерено: обновляется только ПЕРВЫЙ, остальные молча остаются со старой геометрией, и ни одно перестроение этого не чинит. Порядок один: сначала модель, потом разрезы.
  • Вставку фрагмента правят только целиком (заново fragment_place). Экспорт наружу — растр и STEP; DXF/DWG и PDF не пишутся.
  • SVG сервер не читает — и не будет: разбор путей, деление кривых Безье на дуги и разбор вложенности контуров живут во внешнем конвертере, а серверу достаётся готовый список примитивов.

Связанное

  • Проверка окружения (КОМПАС установлен, сервер запускается, подключение живое): команда /kompas:doctor.
  • Установка, требования и настройка сервера: README плагина.
  • Правила проектирования под FDM/FFF-печать: навык kompas-fdm-design.