bc52b5d920
- VariableService: CreateVariableAsync/SetVariableAsync/DeleteVariableAsync/GetVariableValueAsync - создание ТОЛЬКО на ksFeature.VariableCollection (ksPart — только внешние); RebuildModel + re-fetch - Expression — ведущее поле (константа/формула со ссылками); value пересчитывается - list_variables (ModelInspectionService) исправлен: читает feature-коллекцию (все переменные) - инструменты create_variable/set_variable/delete_variable (VariableTools) + DI - интеграционный тест CRUD round-trip (создание, формула width*2, удаление по зависимостям) - ОГРАНИЧЕНИЕ: переменные драйвят геометрию лишь в параметрической модели (эскизы на литералах — нет) - 116 тестов; спек docs/superpowers/specs/2026-05-27-parametrics-design.md
5.8 KiB
5.8 KiB
Дизайн: параметрика (пакет D) — переменные модели
Дата: 2026-05-27 Статус: реализовано и проверено (тест зелёный); на ревью (ревьюер — Codex)
Цель
Дать запись параметрики: создание, изменение и удаление переменных модели (list_variables
уже читает). Это фундамент управляемых моделей: пользовательские переменные, формулы со ссылками,
внешние переменные для сборок.
Сигнатуры (рефлексия interop + справка)
ksVariableCollection:
object AddNewVariable(string name, double value, string note) // создать (ТОЛЬКО на ksFeature!)
object GetByName(string name, bool testFullName, bool testIgnoreCase)
bool RemoveVariable(string name)
int GetCount(); object GetByIndex(int)
ksVariable:
string name; string Expression; double value; bool external; bool Information; string note
ksPart: bool RebuildModel() // применить изменения переменных
ksFeature: object VariableCollection // СВОЙСТВО (не метод), все переменные детали
Ключевые факты (исследование + эмпирика spike)
- Создавать переменные можно только на коллекции корневого
ksFeature(ksPart.GetFeature().VariableCollection), НЕ наksPart.VariableCollection()(та — только внешние).AddNewVariableна ksPart-коллекции не создаёт пользовательскую переменную. Expression— ведущее поле,value— вычисленный результат. Менять значение надо черезExpression(константа «30» или формула «width*2»); прямоеvalue=ненадёжно (перезапишется).- Изменения вступают в силу после
ksPart.RebuildModel();valueпересчитывается изExpression. RCW переменной после RebuildModel «застревает» на старом значении — перечитывать переменную из свежей коллекции (ReadValueFresh). list_variablesисправлен: читалksPart.VariableCollection()(только внешние) → теперьksPart.GetFeature().VariableCollection(все, включая созданные), с фолбэком. Иначе созданная переменная не была бы видна агенту.- Удаление: нельзя удалить переменную, на которую ссылаются другие (RRemoveVariable→FALSE); удалять в порядке зависимостей.
- ОГРАНИЧЕНИЕ (важно для контракта): переменная управляет геометрией только в параметрической модели (размеры эскизов связаны с именами переменных). Наши эскизы строятся литеральными координатами — у них нет именованных размеров, поэтому set_variable хранит/считает значение, но геометрию не меняет. Привязка размеров эскиза к переменным (параметрические эскизы) — отдельный большой пласт (будущее). Поэтому тест проверяет CRUD/вычисление через чтение, а не изменение геометрии.
MCP-инструменты (новая группа, VariableTools)
| Инструмент | Параметры | Поведение |
|---|---|---|
create_variable |
name, value, note?, external=false |
Создать переменную. Возвращает значение. |
set_variable |
name, expression |
Задать выражение (константа/формула), перестроить, вернуть значение. |
delete_variable |
name |
Удалить (нельзя, если есть зависимые). |
Чтение — существующий list_variables (теперь видит все переменные).
Реализация
src/Kompas.Mcp.Core/Modeling/VariableService.cs(новый):CreateVariableAsync,SetVariableAsync,DeleteVariableAsync,GetVariableValueAsync(read-back) на STA-потоке. ХелперRootVariables()→ (ksPart, feature-коллекция);ReadValueFresh(name)после RebuildModel. Валидация: имя не пусто, value конечно, выражение не пусто.VariableTools.cs(новый): 3 инструмента; DIAddSingleton<VariableService>().ModelInspectionService.ReadVariables: источник → feature-коллекция (фолбэк на ksPart).- Транзитные RCW не освобождаем точечно — консистентно (долг v2-2).
Тестирование (Integration, VariableTests)
CRUD round-trip: построить коробку (дерево построения) → create_variable("width",40) (значение 40;
видна в list_variables) → set_variable("width","12+8") → 20 → создать height, set "width*2" →
40 (формула со ссылкой) → удалить height, затем width (порядок зависимостей) → обе исчезли
(GetVariableValueAsync бросает KeyNotFoundException). ✓