# Разведка: параметрические эскизы (управление геометрией переменными)

**Дата:** 2026-05-27
**Статус:** РАЗВЕДКА завершена; реализация НЕ начата (крупный отдельный труд — см. вывод)

## Цель разведки

Можно ли сделать так, чтобы переменная модели (`set_variable`, уже есть) управляла геометрией
эскиза — т.е. реализовать параметрические эскизы? Это «завершение» пакета D.

## Главный вывод

**Параметрические эскизы реализуемы ТОЛЬКО через API7 и требуют отдельной новой подсистемы
построения эскизов** (через `FragmentDocument` + `IDrawingContainer` + ограничения
`ksCDimWithVariable`), несовместимой с текущим API5-путём (`ksDocument2D`). Это многосессионный
архитектурный труд, а не один инкремент. В рамках этой сессии НЕ реализуется.

## Что установлено (рефлексия + исследование справки + spike)

### 1. В API5 управляющего размера нет
Справка (`docs/Kompas3D_SDK/interfaces/ограничения.md`, прим. 2): в API5 **нельзя** создать
ограничения **«Размер с переменной» (`ksCDimWithVariable=13`)** и «Фиксированный размер»
(`ksCFixedDim=14`). А именно они нужны, чтобы размер управлял геометрией. `ksDocument2D.ksLinDimension`
создаёт лишь аннотационный (неуправляющий) размер. Значит API5-путь (наш текущий) для параметрики
непригоден.

### 2. Управляющий размер — только через API7 `IParametriticConstraint`
- `IDrawingObject1.NewConstraint()` → `IParametriticConstraint`; `ConstraintType=ksCDimWithVariable`,
  `Variable` (уникальное имя), `Expression`/`Value`, `Create()`. Всё это ЕСТЬ в interop
  (`KompasAPI7.dll`: `IDrawingObject1`, `IParametriticConstraint`, `ksConstraintTypeEnum`).
- При установке своего имени переменной надо следить за уникальностью, иначе «Недопустимое имя».

### 3. SPIKE: API5-эскиз через API7 НЕ аннотируется
Проба (`ISketch` последнего эскиза → `ISketch.Curves`) показала **`Curves == null`** для эскиза,
построенного и закрытого через API5 `ksDocument2D`. Значит «достроить параметрику поверх нашего
API5-эскиза» через `ISketch.Curves` НЕ работает.

### 4. Правильный путь — целиком через API7 FragmentDocument
- `ISketch.BeginEdit()` → **`FragmentDocument`** (`IKompasDocument2D`).
- `IKompasDocument2D.ViewsAndLayersManager` → вид → `IDrawingContainer`.
- `IDrawingContainer` — типизированные коллекции: `LineSegments`, `Rectangles`, `Circles`, `Arcs`,
  `Points`, `Nurbses`, … (`.Add()` создаёт объект-кривую = `IDrawingObject1`).
- На объекте-кривой → `NewConstraint(ksCDimWithVariable)` с именем переменной.
- `ISketch.EndEdit()` → перестроение.

То есть параметрический эскиз строится **другим API** (API7 drawing objects), чем наш текущий
(`PartModeler.Sketch.cs` на API5 `ksDocument2D`). Это новая параллельная подсистема эскизов.

## Объём работ для реализации (оценка)

1. Новый сервис/слой построения эскиза через API7 (`ISketch.BeginEdit`→`FragmentDocument`→
   `IDrawingContainer`): создание отрезков/прямоугольников/окружностей через API7-коллекции.
2. Наложение геометрических ограничений (`ksSetObjConstraint`/API7) — фиксация, горизонталь/
   вертикаль — чтобы при изменении размера эскиз не «расплывался».
3. Управляющие размеры `ksCDimWithVariable` с именами переменных, увязанные с моделью переменных
   (уже есть `VariableService`).
4. Интеграция с существующими формообразующими (выдавить такой эскиз) и реестром `_features`.
5. Эмпирическая проверка ОСТАЁТСЯ открытой: пересчитывает ли решатель эскиза геометрию при
   изменении переменной из ВНЕШНЕЙ автоматизации (не проверено — это ключевой риск).

## Решающий spike (API7, выполнен) — ОТРИЦАТЕЛЬНЫЙ результат

Построен полный API7-путь и проверено управление геометрией:
`IModelContainer.Sketchs.Add()` → `ISketch.Plane = part.DefaultObject[o3d_planeXOY]` →
`ISketch.BeginEdit()` → `FragmentDocument` → `ViewsAndLayersManager.Views.ActiveView`
(приводится к `IDrawingContainer`) → `LineSegments.Add()` (создаёт `ILineSegment` = `IDrawingObject1`).
Геометрия строится — ОК. Дальше пробовали наложить размер-переменную и проверить, следует ли длина
за переменной `plen` (создана заранее), после `RebuildModel`:

- **`ksCDimWithVariable` (тип 13, «размер с переменной») — `Create()` = FALSE** (и с авто-именем, и
  с явным `Variable="plen"`, и с/без `Expression`/`Value`/`SegmentIndex`). Ограничение, ради которого
  всё затевалось, через `IDrawingObject1.NewConstraint()` на отрезке эскиза НЕ создаётся.
- **`ksCFixedLenght` (тип 19) — `Create()` = TRUE, НО привязан к литеральному `Value`**, а
  `Expression="plen"` игнорируется: после `plen`: 50→80 длина осталась **50** (не 80). `Variable` пуст.
- `ksCFixedPoint`, `ksCFixedLenght` создаются; `ksCDimWithVariable`, `ksCFixedDim` — нет.

**Итог:** через доступные пути COM-автоматизации связать размер эскиза с переменной модели
(чтобы её изменение двигало геометрию) НЕ удаётся: нужный тип ограничения `ksCDimWithVariable` не
строится, а рабочий `ksCFixedLenght` не привязывается к переменной. Вероятно, `ksCDimWithVariable`
требует контекста, недоступного внешней автоматизации (интерактивная простановка размера / иной
порядок создания, не отражённый в справке).

## Рекомендация (обновлено по итогам spike)

Управляемые переменными эскизы через текущий COM-API **признаны нереализуемыми** (`ksCDimWithVariable`
не строится из внешней автоматизации). Не тратить на этот путь время повторно. Возможные направления,
если тема снова станет приоритетной:
- Проверить, не строится ли `ksCDimWithVariable` через **API5** `ksSetObjConstraint` (хотя справка
  говорит, что в API5 этот тип недоступен — подтвердить рефлексией/пробой).
- Попробовать создавать размер как самостоятельный объект-аннотацию (не через `NewConstraint` на
  отрезке) и затем связывать — но коллекции размеров у `IDrawingContainer` нет (только геометрия).
- Принять, что параметрика ограничена **CRUD переменных** (пакет D, готово) — переменные полезны
  для импортированных параметрических моделей и как информационные; управление геометрией из
  внешней автоматизации в этой версии КОМПАС/SDK недоступно.

Пакет D = переменные (create/set/delete + чтение), без привязки к геометрии — зафиксировано честно
в документации и описаниях инструментов.
