docs: уклон (draft, API5 Incline) — README/CLAUDE/ARCHITECTURE/OPEN_QUESTIONS/presentation, 64 инструмента, 115 тестов

This commit is contained in:
2026-05-27 10:35:16 +03:00
parent 143877c6cc
commit 72045c8a84
5 changed files with 32 additions and 23 deletions
+9 -2
View File
@@ -146,10 +146,17 @@ stateful-сессии? Пока полагаемся на последовате
Ключевые паттерны: дерево — `ksPart.GetFeature()``SubFeatureCollection(true,false)`; тела — `BodyCollection()``ksBody`; переменные — `VariableCollection()``ksVariable`. Детект «импорт без истории»: `bodyCount>0 && нет формообразующих операций && features.Count<=bodyCount+1`. Итог: **62 инструмента, 101 тест.**
### ✅ hole — реализован через API7
**Решено.** Инструмент `hole` добавлен как первая формообразующая операция на API7 — в API5 интерфейс `ksHoleDefinition` отсутствует в interop (аналогично `draft`; `o3d_holeOperation=52` есть, но определения нет). Новый сервис `HoleService` (`src/Kompas.Mcp.Core/Modeling/HoleService.cs`) не является методом `PartModeler`.
**Решено.** Инструмент `hole` добавлен через API7 — в API5 интерфейс `ksHoleDefinition` отсутствует в interop (`o3d_holeOperation=52` есть, но определения нет). Новый сервис `HoleService` (`src/Kompas.Mcp.Core/Modeling/HoleService.cs`) не является методом `PartModeler`.
Паттерн размещения: `(IModelContainer)part7``Points3D.Add()` (создаёт `IPoint3D` как центр) → `Holes3D.Add()``IHole3D``(IHoleDisposal)hole` (`BaseSurface` = грань по `FindObjectsByPoint`, `Perpendicular=true`, `AssociationVertex=point`) → `Update()``RebuildDocument()`. Эскиз размещения не нужен.
**Ключевая тонкость — направление по объёму:** `Update()` возвращает TRUE даже если сверлит «в воздух» снаружи тела (убыли материала нет). Решение: попытка `Direction=true` → Rebuild → сравниваем объём через API5 `CalcMassInertiaProperties`; если не убыл — пробуем `Direction=false`. Тот же класс проблем, что у boss/cut на грани (непредсказуемая ориентация нормали). При неуспехе обеих попыток — откат через `IFeature7.Delete()`. Добавлена валидация `double.IsFinite` (Infinity проходил мимо `>0`).
Отверстие не попадает в реестр `_features` API5 → возвращает подтверждение без id. +3 интеграционных теста (`HoleTests.cs`). Итог: **63 инструмента, 104 теста (60 unit + 44 integration).**
Отверстие не попадает в реестр `_features` API5 → возвращает подтверждение без id. +3 интеграционных теста (`HoleTests.cs`).
### ✅ draft (уклон) — реализован через API5 Incline, а не API7
**Решено.** Ранее считалось, что уклон недоступен в API5 и требует API7. Это было заблуждением: поиск вёлся по слову "Draft", тогда как операция в API5 называется **Incline** (`ksInclineDefinition`, `o3d_incline=42`). Реализация — стандартный API5-паттерн `PartModeler` (как shell/rib/loft): `NewEntity(o3d_incline)``ksInclineDefinition``FaceArray()` (грани по индексам) → `SetPlane(координатная плоскость)``angle``direction``Create()` → регистрация в `_features`.
**Ключевая тонкость (эмпирика):** `direction=false`=расширение (outward), `direction=true`=сужение — **обратно справке**. Маппинг в коде: `def.direction = !outward`. Тот же класс проблем с направлением, что у boss/cut (v2-1). Валидация угла вынесена в `SketchGeometry.RequireDraftAngle(0<angle<90)`. +9 unit-тестов + 2 integration-теста. Итог: **64 инструмента, 115 тестов (69 unit + 46 integration).**
Примечание: `o3d_DraftFromEdges=644` / `IDraftFromEdges` — это другая операция «уклон от базовой линии» (API7), здесь не используется.