From 86a5a523476490ba96477e819196a0c62c479249 Mon Sep 17 00:00:00 2001 From: Shahovalov MIkhail Date: Wed, 27 May 2026 19:58:15 +0300 Subject: [PATCH] =?UTF-8?q?review(drawing):=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?Codex=20(=D1=83=D0=B3=D0=BB=D0=BE=D0=B2=D0=BE=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=BC=D0=B5=D1=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - описание (x3,y3) и сообщение об ошибке: угол выбирает angleType, не точка дуги - тест angleType=Max (лучи 0°/45° → 135° тупой супплемент): min=45/max=135/more=315 - спек дополнен находкой о трёх типах угла 241 тест зелёный, сборка Release чистая. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...drawing-radial-angular-dimension-design.md | 27 +++++++++++++++---- .../Drawings/DrawingService.cs | 6 ++--- src/Kompas.Mcp.Host/Tools/DrawingTools.cs | 2 +- .../Integration/DrawingAngularTests.cs | 16 +++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/docs/superpowers/specs/2026-05-27-drawing-radial-angular-dimension-design.md b/docs/superpowers/specs/2026-05-27-drawing-radial-angular-dimension-design.md index 35a1331..95af0ad 100644 --- a/docs/superpowers/specs/2026-05-27-drawing-radial-angular-dimension-design.md +++ b/docs/superpowers/specs/2026-05-27-drawing-radial-angular-dimension-design.md @@ -6,10 +6,27 @@ ## Уточнение по реализации (важно) Спайк изначально решил, что измеряемый сектор выбирает положение дуги `(x3,y3)`. **При реализации -выяснилось иначе:** сектор (90° vs 270°) выбирает **`angleType`** (`ksADMinAngle`/`MaxAngle`/`MoreAngle`), +выяснилось иначе:** какой угол измерять, выбирает **`angleType`** (`ksADMinAngle`/`MaxAngle`/`MoreAngle`), а `(x3,y3)` лишь позиционирует размерную дугу и задаёт её радиус. (270° в спайке возникал потому, что -`X3/Y3` не были заданы = совпадали с вершиной → вырождение.) Проверено: `angleType=Min`→90°, -`angleType=More`→270° на одной геометрии. Тест #8 и описания инструмента/сервиса исправлены под это. +`X3/Y3` не были заданы = совпадали с вершиной → вырождение.) + +Три типа дают **три разных угла** (проверено на лучах 0° и 45°): +- `Min` (`ksADMinAngle`) → **45°** (острый); +- `Max` (`ksADMaxAngle`) → **135°** (тупой супплемент, 180−45); +- `More` (`ksADMoreAngle`) → **315°** (рефлексный, 360−45). + +Тесты (#8 More→270 на 90°, Max→135 на 45°) и описания инструмента/сервиса исправлены под это. + +## Правки по ревью Codex (реализация) + +- **#1** описание параметра `x3,y3` в инструменте переформулировано (точка позиционирует дугу; угол + выбирает `angleType`, не она). +- **#2** сообщение пост-проверки углового больше не винит `(x3,y3)` — указывает на коллинеарность сторон. +- **#3** добавлен интеграционный тест `angleType=Max` (лучи 0°/45° → 135°) — покрыл маппинг `ksADMaxAngle`, + отличный от `Min`/`More`. +- **#4** (откат радиального не тестируется) — **отклонено с обоснованием:** как у диаметрального + (`radius>0` → всегда `Valid`, `value=radius>0`; детерминированного пост-Add сбоя нет), код отката + структурно идентичен протестированному угловому (коллинеарный путь, счётчик не меняется). ## Правки по ревью Codex (спек) @@ -149,8 +166,8 @@ RCW точечно не освобождаем (консистентно с ли 5. **Измеряет 90°**: вершина(0,0), (10,0)&(0,10), x3/y3=(5,5) → `Value ≈ 90`. 6. **Измеряет 45°**: вершина(0,0), (10,0)&(10,10), x3/y3=(8,4) → `Value ≈ 45`. 7. **Попадание в вид**: `AngleDimensions.Count` целевого вида +1. -8. **Выбор угла типом** (#2): та же геометрия 90°, но `angleType=More` → `Value ≈ 270` - (документированное поведение: какой из двух углов измерять, выбирает `angleType`, не `x3,y3`). +8. **Выбор угла типом** (#2): `angleType=More` на геометрии 90° → `Value ≈ 270`; `angleType=Max` + на лучах 0°/45° → `Value ≈ 135` (тупой супплемент). Какой угол измерять, выбирает `angleType`, не `x3,y3`. 9. **Вырожденный угол до Add** (вершина совпадает с точкой стороны) → `ArgumentException`. 10. **Откат после Add** (#3): коллинеарные сонаправленные лучи (0,0),(10,0),(20,0) → угол ≈0 → `InvalidOperationException`; `AngleDimensions.Count` целевого вида НЕ изменился (откат `Delete`). diff --git a/src/Kompas.Mcp.Core/Drawings/DrawingService.cs b/src/Kompas.Mcp.Core/Drawings/DrawingService.cs index 37a2afb..ba87a2f 100644 --- a/src/Kompas.Mcp.Core/Drawings/DrawingService.cs +++ b/src/Kompas.Mcp.Core/Drawings/DrawingService.cs @@ -268,11 +268,11 @@ public sealed class DrawingService throw new InvalidOperationException("Угловой размер построен невалидным."); var value = ((IDimensionText)dim).NominalValue; // градусы - // Нулевой/некорректный угол — стороны коллинеарны (сонаправлены) или (x3,y3) вне сектора. + // Нулевой/некорректный угол — стороны коллинеарны (лучи сонаправлены → угол вырожден). if (value <= 0 || !double.IsFinite(value)) throw new InvalidOperationException( - $"Угловой размер измерил некорректное значение ({value}°). Стороны коллинеарны или " + - "положение дуги (x3,y3) задаёт вырожденный сектор."); + $"Угловой размер измерил некорректное значение ({value}°) — стороны коллинеарны " + + "(лучи (xc,yc)→(x1,y1) и (xc,yc)→(x2,y2) сонаправлены)."); return new DrawingDimensionResult { Value = value, ViewNumber = view.Number }; } catch diff --git a/src/Kompas.Mcp.Host/Tools/DrawingTools.cs b/src/Kompas.Mcp.Host/Tools/DrawingTools.cs index def3692..b74aba3 100644 --- a/src/Kompas.Mcp.Host/Tools/DrawingTools.cs +++ b/src/Kompas.Mcp.Host/Tools/DrawingTools.cs @@ -117,7 +117,7 @@ public sealed class DrawingTools(KompasSession session, DrawingService drawing) [Description("Y точки на стороне 1")] double y1, [Description("X точки на стороне 2")] double x2, [Description("Y точки на стороне 2")] double y2, - [Description("X положения размерной дуги (внутри измеряемого сектора)")] double x3, + [Description("X положения размерной дуги (отстоит от вершины; угол выбирает angleType, не эта точка)")] double x3, [Description("Y положения размерной дуги")] double y3, [Description("Тип угла: min | max | more")] string angleType = "min", [Description("Номер вида (0 = первый/главный)")] int viewNumber = 0) diff --git a/tests/Kompas.Mcp.Tests/Integration/DrawingAngularTests.cs b/tests/Kompas.Mcp.Tests/Integration/DrawingAngularTests.cs index e582821..31ae332 100644 --- a/tests/Kompas.Mcp.Tests/Integration/DrawingAngularTests.cs +++ b/tests/Kompas.Mcp.Tests/Integration/DrawingAngularTests.cs @@ -75,6 +75,22 @@ public sealed class DrawingAngularTests : IntegrationTestBase finally { await _docs.CloseAsync(save: false); } } + [Fact] + public async Task Angle_type_max_measures_larger_angle() + { + await NewDrawingWithViewsAsync(); + try + { + // Лучи 0° и 45°: три типа дают разные углы — min=45 (острый), max=135 (тупой + // супплемент 180−45), more=315 (рефлексный). Покрывает маппинг ksADMaxAngle (≠ Min/More). + var r = await _drawing.AddAngularDimensionAsync( + viewNumber: 0, xc: 0, yc: 0, x1: 10, y1: 0, x2: 10, y2: 10, x3: 4, y3: -8, + angleType: AngleDimensionType.Max); + Assert.InRange(r.Value, 134.0, 136.0); + } + finally { await _docs.CloseAsync(save: false); } + } + [Fact] public async Task Targets_specific_view_and_increments_angular_count() {