From b6cd92b95cce69980e499d1ab4b1a119ed169dc5 Mon Sep 17 00:00:00 2001 From: Shahovalov MIkhail Date: Wed, 27 May 2026 18:17:15 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D1=81=D0=BF=D0=B5=D0=BA=20drawing=5Fad?= =?UTF-8?q?d=5Fdiametral=5Fdimension=20=E2=80=94=20=D0=B4=D0=B8=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=20(API7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Веха 2D-ЧЕРТЁЖ, инкремент 4. Спайк: (ISymbols2DContainer)view.DiametralDimensions. Add → Xc/Yc/Radius/Angle(рад) → Update; NominalValue == диаметр (2R, проверено 30). Angle экспонируется в градусах. Та же модель, что линейный размер. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...5-27-drawing-diametral-dimension-design.md | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-27-drawing-diametral-dimension-design.md diff --git a/docs/superpowers/specs/2026-05-27-drawing-diametral-dimension-design.md b/docs/superpowers/specs/2026-05-27-drawing-diametral-dimension-design.md new file mode 100644 index 0000000..cc273cb --- /dev/null +++ b/docs/superpowers/specs/2026-05-27-drawing-diametral-dimension-design.md @@ -0,0 +1,81 @@ +# Дизайн: диаметральный размер на виде чертежа (drawing_add_diametral_dimension) через API7 + +**Дата:** 2026-05-27 +**Статус:** спайк зелёный (значение=диаметр подтверждено); спроектировано; на ревью (Codex) + +## Цель + +Веха 2D-ЧЕРТЁЖ, инкремент 4. После линейного размера — **диаметральный** размер окружности на виде +(Ø для отверстий/цилиндров — частый случай конструкторского чертежа). Радиальный (с ветвями) и +угловой — следующие инкременты. + +## Спайк: механизм подтверждён (НЕ разучивать) + +Та же модель, что у линейного размера (`ISymbols2DContainer` QI от вида). Спайк +(`DrawingDiametralSpikeTests`, зелёный): + +``` +ISymbols2DContainer symbols = (ISymbols2DContainer)view; // QI от конкретного IView +IDiametralDimension dim = symbols.DiametralDimensions.Add(); +dim.Xc = xc; dim.Yc = yc; // центр окружности (ЛОКАЛЬНАЯ СК вида, мм) +dim.Radius = radius; // радиус окружности (мм) +dim.Angle = angleRad; // направление выноски (РАДИАНЫ) +bool ok = dim.Update(); +double value = ((IDimensionText)dim).NominalValue; // = ДИАМЕТР (2·Radius) +``` + +**Проверено:** `Xc=10,Yc=10,Radius=15,Angle=0.785` → `Update=True`, `Valid=True`, +`NominalValue == 30` (= диаметр = 2·Radius). `Angle` — в **радианах** (конвенция 2D-API КОМПАС; +для размера задаёт лишь направление выноски, на значение не влияет). + +**Координаты** — локальная СК вида (как у линейного). Размер «свободный» (по Xc/Yc/Radius), без +ассоциативной привязки к геометрии (`BaseObject` не задаём — будущее). + +## MCP-инструмент + +| Инструмент | Параметры | Поведение | +|---|---|---| +| `drawing_add_diametral_dimension` | `xc,yc` (центр), `radius`, `angle=0` (°), `viewNumber=0` | Поставить диаметральный размер (Ø) окружности с центром (xc,yc) и радиусом `radius` (ЛОКАЛЬНАЯ СК вида, мм) на виде. `angle` — направление выноски в ГРАДУСАХ (внутри → радианы). `viewNumber`: 0 = первый/главный вид. Значение (диаметр = 2·radius) измеряется автоматически. Возвращает диаметр и номер вида. | + +`angle` экспонируется в **градусах** (LLM-дружелюбно), внутри умножается на π/180. + +## Архитектура + +В существующем `DrawingService` (рядом с `AddLinearDimensionAsync`); переиспользуем `FindView`, +`DrawingDimensionResult`, паттерн отката. + +- `DrawingService.AddDiametralDimensionAsync(viewNumber, xc, yc, radius, angleDeg, ct)`. +- Инструмент `drawing_add_diametral_dimension` в `DrawingTools`. +- Helper `GetViewDiametralDimensionCountAsync` (для теста — попадание в вид; размеры в + `ISymbols2DContainer`, не в `ObjectCount` — как выяснено для линейных). + +## Валидация (чистые static, unit-тест) + +- `DrawingValidation.RequireFiniteCoords(xc, yc, angleDeg)` (уже есть). +- `DrawingValidation.RequirePositiveRadius(double radius)` (новый) — конечный и `> 0`. + +## Реализация + +`AddDiametralDimensionCore`: валидация (coords + radius>0) → `FindView` → `(ISymbols2DContainer)view` +→ `DiametralDimensions.Add()` (null-check) → `Xc/Yc/Radius`, `Angle = angleDeg·π/180` → `Update()` +(FALSE → откат `dim.Delete` + ошибка) → `Valid` (false → откат) → `value = ((IDimensionText)dim). +NominalValue` (диаметр); если `≤ 0` → откат + ошибка → вернуть `DrawingDimensionResult { Value, ViewNumber }`. +RCW точечно не освобождаем (v2-2). + +## Тестирование + +### Unit (`DrawingValidationTests`) +- `RequirePositiveRadius` — бросает на 0/отрицательном/NaN/Infinity; пропускает положительный. + +### Integration (`DrawingDiametralTests`) +1. **Значение = диаметр**: Radius=15 → `Value ≈ 30`. +2. **Попадание в вид**: `*DiametralDimensions.Count` целевого вида +1 (адресация по `viewNumber` из + `ViewNumbers`). +3. **Радиус ≤ 0** → `ArgumentOutOfRangeException` (откат не нужен — до `Add`). +4. **Нет видов** → понятная ошибка. + +(Сценарий 1 = промотированный спайк; спайк-файл удаляется.) + +## Дальнейшее (вне спека) +- Радиальный размер (`RadialDimensions`, ветви), угловой; ассоциативная привязка к окружности вида + (`BaseObject`); рамка/формат листа.