From d318525e45f700b1f427c4f0af4b40f07b34c7a7 Mon Sep 17 00:00:00 2001 From: Shahovalov MIkhail Date: Tue, 26 May 2026 22:55:48 +0300 Subject: [PATCH] =?UTF-8?q?fix(feature):=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20rib=20=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20?= =?UTF-8?q?Codex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - thickness через RequirePositive (NaN-safe) + проверка angle на IsFinite - описание side нейтральное (ksRibSideEnum), без 'ортогонально' - тест: проверка объёма L-уголка (before), комментарий side=left Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Kompas.Mcp.Core/Modeling/PartModeler.Features.cs | 3 ++- src/Kompas.Mcp.Host/Tools/FeatureTools.cs | 2 +- tests/Kompas.Mcp.Tests/Integration/FeatureOpsTests.cs | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Kompas.Mcp.Core/Modeling/PartModeler.Features.cs b/src/Kompas.Mcp.Core/Modeling/PartModeler.Features.cs index 39be616..ce3b205 100644 --- a/src/Kompas.Mcp.Core/Modeling/PartModeler.Features.cs +++ b/src/Kompas.Mcp.Core/Modeling/PartModeler.Features.cs @@ -237,7 +237,8 @@ public sealed partial class PartModeler public Task RibAsync(int sketchId, double thickness, string side = "up", bool symmetric = true, double angle = 0, CancellationToken ct = default) => _dispatcher.InvokeAsync(() => { - if (thickness <= 0) throw new ArgumentOutOfRangeException(nameof(thickness), "Толщина должна быть > 0."); + SketchGeometry.RequirePositive(thickness, nameof(thickness)); // ловит и NaN (!(NaN>0)) + if (!double.IsFinite(angle)) throw new ArgumentException("Угол уклона должен быть конечным числом.", nameof(angle)); var sideCode = SketchGeometry.RibSide(side); var sketch = RequireSketch(sketchId); CloseSketchCore(sketch); // эскиз должен быть закрыт перед операцией diff --git a/src/Kompas.Mcp.Host/Tools/FeatureTools.cs b/src/Kompas.Mcp.Host/Tools/FeatureTools.cs index 9fd020b..5ded76b 100644 --- a/src/Kompas.Mcp.Host/Tools/FeatureTools.cs +++ b/src/Kompas.Mcp.Host/Tools/FeatureTools.cs @@ -105,7 +105,7 @@ public sealed class FeatureTools(KompasSession session, PartModeler modeler) } [McpServerTool(Name = "rib")] - [Description("Построить ребро жёсткости от разомкнутого контура эскиза до тела. sketchId — эскиз с разомкнутым контуром (отрезок/ломаная) на плоскости, пересекающей тело. thickness — толщина стенки ребра (мм). side — направление достройки до тела: left|right (вдоль плоскости эскиза) или up|down (ортогонально плоскости). symmetric=true — толщина симметрична плоскости эскиза, false — в одну сторону. angle — уклон стенок (градусы). Возвращает id операции.")] + [Description("Построить ребро жёсткости от разомкнутого контура эскиза до тела. sketchId — эскиз с разомкнутым контуром (отрезок/ломаная) на плоскости, пересекающей тело. thickness — толщина стенки ребра (мм). side — направление достройки полотна до тела (ksRibSideEnum): left|right|up|down (если ребро не строится — перебрать значения). symmetric=true — толщина симметрична плоскости эскиза, false — в одну сторону. angle — уклон стенок (градусы). Возвращает id операции.")] public async Task Rib(int sketchId, double thickness, string side = "up", bool symmetric = true, double angle = 0) { await session.ConnectAsync(); diff --git a/tests/Kompas.Mcp.Tests/Integration/FeatureOpsTests.cs b/tests/Kompas.Mcp.Tests/Integration/FeatureOpsTests.cs index 5b919f5..5429d0c 100644 --- a/tests/Kompas.Mcp.Tests/Integration/FeatureOpsTests.cs +++ b/tests/Kompas.Mcp.Tests/Integration/FeatureOpsTests.cs @@ -63,10 +63,10 @@ public sealed class FeatureOpsTests await _modeler.CloseSketchAsync(sBody); await _modeler.ExtrudeAsync(sBody, depth: 30); var before = (await _query.GetPartInfoAsync()).Volume; - Assert.True(before > 0); + Assert.InRange(before, 11250 * 0.95, 11250 * 1.05); // L-уголок 375·30 - // Ребро-косынка: разомкнутый отрезок-диагональ во внутреннем углу, на XOZ (Y=0). - // side=up (ортогонально, +Y), несимметрично → растёт от Y=0 вглубь тела на 5 мм. + // Ребро-косынка: разомкнутый отрезок во внутреннем углу, на XOZ (Y=0). + // Контур висит в зазоре (не касается полок); side=left, несимметрично → толщина 5 мм. var sRib = await _modeler.OpenSketchAsync(BasePlane.XOZ); await _modeler.AddLineAsync(sRib, 25, 10, 10, 25); // висит в пустом углу, не касаясь полок await _modeler.CloseSketchAsync(sRib);