feat(query): габариты детали (get_bounding_box)

QueryService.GetBoundingBoxAsync через API5 ksPart.GetGabarit(full=false) →
габаритный параллелепипед (мм) + размеры по осям. Помогает агенту оценить
протяжённость модели и подбирать точки для select-by-point (грани/рёбра).
Новый инструмент get_bounding_box; запись BoundingBox.

Тест: цилиндр R10×H20 → X,Y ∈ [-10;10], Z ∈ [0;20] (расширен QueryTests).
Презентация: 26 инструментов.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@
This commit is contained in:
2026-05-26 10:03:53 +03:00
parent 88dad09ea7
commit 8c778a449d
5 changed files with 66 additions and 4 deletions
+16
View File
@@ -0,0 +1,16 @@
namespace Kompas.Mcp.Core.Query;
/// <summary>Габаритный параллелепипед детали (мировые координаты модели, мм).</summary>
public sealed record BoundingBox
{
public required double MinX { get; init; }
public required double MinY { get; init; }
public required double MinZ { get; init; }
public required double MaxX { get; init; }
public required double MaxY { get; init; }
public required double MaxZ { get; init; }
public double SizeX => MaxX - MinX;
public double SizeY => MaxY - MinY;
public double SizeZ => MaxZ - MinZ;
}
+28
View File
@@ -60,4 +60,32 @@ public sealed class QueryService
if (Marshal.IsComObject(part)) Marshal.ReleaseComObject(part);
}
}, ct);
/// <summary>Габаритный параллелепипед активной детали (по телам), мм.</summary>
public Task<BoundingBox> GetBoundingBoxAsync(CancellationToken ct = default)
=> _dispatcher.InvokeAsync(() =>
{
var doc3d = _session.Kompas.ActiveDocument3D() as ksDocument3D
?? throw new InvalidOperationException("Нет активного 3D-документа.");
var part = doc3d.GetPart((short)Part_Type.pTop_Part) as ksPart
?? throw new InvalidOperationException("Не удалось получить вершинный компонент (ksPart).");
try
{
// full=false → только тела (без вспомогательной геометрии); customizable игнорируется.
if (!part.GetGabarit(false, false,
out double x1, out double y1, out double z1,
out double x2, out double y2, out double z2))
throw new InvalidOperationException("GetGabarit вернул FALSE (модель пуста?).");
return new BoundingBox
{
MinX = Math.Min(x1, x2), MinY = Math.Min(y1, y2), MinZ = Math.Min(z1, z2),
MaxX = Math.Max(x1, x2), MaxY = Math.Max(y1, y2), MaxZ = Math.Max(z1, z2),
};
}
finally
{
if (Marshal.IsComObject(part)) Marshal.ReleaseComObject(part);
}
}, ct);
}
+10
View File
@@ -18,4 +18,14 @@ public sealed class QueryTools(KompasSession session, QueryService query)
return $"Объём: {i.Volume:F2} мм³; масса: {i.Mass:F4} кг; площадь: {i.Area:F2} мм²; " +
$"центр масс: ({i.CenterX:F2}, {i.CenterY:F2}, {i.CenterZ:F2}).";
}
[McpServerTool(Name = "get_bounding_box")]
[Description("Габариты активной детали: координаты габаритного параллелепипеда (мм) и его размеры. Помогает оценить протяжённость модели и подобрать точки для выбора граней/рёбер.")]
public async Task<string> GetBoundingBox()
{
await session.ConnectAsync();
var b = await query.GetBoundingBoxAsync();
return $"Габарит: X [{b.MinX:F2}; {b.MaxX:F2}], Y [{b.MinY:F2}; {b.MaxY:F2}], Z [{b.MinZ:F2}; {b.MaxZ:F2}]; " +
$"размеры (Д×Ш×В): {b.SizeX:F2} × {b.SizeY:F2} × {b.SizeZ:F2} мм.";
}
}